"""Functions to monitor memory related metrics"""
import logging
from perfmon.core.metrics.common import get_cumulative_metric_value
from perfmon.common.utils.execute_cmd import execute_cmd
from perfmon.common.utils.parsing import get_parser
_log = logging.getLogger(__name__)
# Cache line - 64 bytes
CACHE_LINE = 64.0
# Measuring time for memory bw event
MEM_BW_MEASURE_TIME = 2
# pylint: disable=E0401,W0201,C0301
[docs]def get_memory_bandwidth(mem_bw_event, procs):
"""This method returns memory bandwidth based on perf LLC load misses event"""
# Get all child processes
pids = [p.pid for p in procs]
# Command string to probe for LLC load misses
cmd_str = 'perf stat -e {} -p {} sleep {}'.format(
mem_bw_event, ','.join([str(pid) for pid in pids]), MEM_BW_MEASURE_TIME
)
# Execute command
cmd_out = execute_cmd(cmd_str)
parse_perf_out = get_parser(cmd_out, reg='perf')
# Parse the value of LLC Local miss
llc_local_miss_string = parse_perf_out('LLC_MISS_LOCAL')
# Parse the value of LLC remote miss
llc_remote_miss_string = parse_perf_out('LLC_MISS_REMOTE')
# Convert load misses to memory bandwidth
try:
llc_local_miss_data = int(llc_local_miss_string.rstrip().replace(',', ''))
llc_remote_miss_data = int(llc_remote_miss_string.rstrip().replace(',', ''))
mem_bw = (llc_local_miss_data + llc_remote_miss_data) * CACHE_LINE / MEM_BW_MEASURE_TIME
except ValueError:
mem_bw = 0
return mem_bw
[docs]def memory_usage(mem_bw_event, procs, data):
"""This method gets memory usage"""
# Get cumulative memory info for the process and its childs
data = get_cumulative_metric_value('memory_info', procs, data)
# Get cumulative full memory info (uss and shared) for the process and its childs
data = get_cumulative_metric_value('memory_full_info', procs, data)
# Get cumulative memory percent for the process and its childs
data = get_cumulative_metric_value('memory_percent', procs, data)
# Get bandwidth info if perf event is found
if mem_bw_event:
data['memory_bw'].append(get_memory_bandwidth(mem_bw_event, procs))
return data