# Copyright 2017 The Chromium OS Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. import logging import re from autotest_lib.client.bin import test, utils from autotest_lib.client.common_lib import error _RESULT_STRING = 'Average page access speed: (\d+)' class hardware_MemoryZRAMThroughput(test.test): """ This test uses a large buffer to measure the page access throughput with and without ZRAM. """ version = 1 def initialize(self): utils.system('stop ui', ignore_status=True) self._PATTERN = re.compile(_RESULT_STRING) def _log_results(self, key, out): logging.info("test output: %s", out) pages_per_second = 0 data_points = 0 for line in out.splitlines(): result = self._PATTERN.match(line) if result: pages_per_second += float(result.group(1)) data_points += 1 continue if data_points == 0: raise error.TestError('Test results not found') # Take the average of all data points. Currently when --fork is # passed to memory-eater, there will be two data points from two # processes. average_pages_per_second = pages_per_second / data_points self.output_perf_value(description=key, value=average_pages_per_second, higher_is_better=True, units='pages_per_sec') return average_pages_per_second def run_once(self): mem_size = utils.memtotal() swap_size = utils.swaptotal() logging.info("MemTotal: %.0f KB", mem_size) logging.info("SwapTotal: %.0f KB", swap_size) # First run memory-eater wth 60% of total memory size to measure the # page access throughput cmd = ("memory-eater --size %d --speed --repeat 4 --chunk 500 " "--wait 0" % long(mem_size * 0.60 / 1024)) logging.debug('cmd: %s', cmd) out = utils.system_output(cmd) self._log_results("60_Percent_RAM", out) # Then run memory-eater wth total memory + 30% swap size to measure the # page access throughput. On 32-bit system with 4GB of RAM, the memory # footprint needed to generate enough memory pressure is larger than # a single user-space process can own. So we divide the memory usage # by half and the test itself will fork a child process to double the # memory usage. Each process will take turns to access 500 pages # (via --chunk) until all pages are accessed 4 times (via --repeat). half_mem_pressure_size = long((mem_size+swap_size * 0.3) / 1024) / 2; cmd = ("memory-eater --size %d --speed --fork --repeat 4 --chunk 500" "--wait 0" % half_mem_pressure_size) logging.debug('cmd: %s', cmd) out = utils.system_output(cmd) self._log_results("30_Percent_SWAP", out) def cleanup(self): utils.system('start ui')