mirror of
https://github.com/GopeedLab/gopeed.git
synced 2026-11-14 12:23:43 +00:00
research: compare process CPU and memory for moejs workloads
This commit is contained in:
1 parent
941fda7d13
commit
9504e33a44
10 files changed
+7792
-2
No files matched your search
@@ -0,0 +1,88 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Measure equal extension work in fresh OS processes, never CPU percentage."""
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
import statistics
|
||||
import subprocess
|
||||
import tempfile
|
||||
|
||||
root = Path(__file__).resolve().parent
|
||||
os.chdir(root)
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--repeats', type=int, default=5)
|
||||
options = parser.add_mutually_exclusive_group()
|
||||
options.add_argument('--smoke', action='store_true')
|
||||
options.add_argument('--memory-only', action='store_true', help='replace retained samples, keeping saved CPU samples')
|
||||
options.add_argument('--summarize-only', action='store_true')
|
||||
args = parser.parse_args()
|
||||
if args.repeats < 1:
|
||||
parser.error('--repeats must be positive')
|
||||
all_workloads = [('cold',20),('warm',200),('retained',1),('retained',8)]
|
||||
workloads = [('cold',2),('warm',2),('retained',2)] if args.smoke else all_workloads
|
||||
filename = 'resources-smoke.json' if args.smoke else 'resources.json'
|
||||
rows = []
|
||||
if args.summarize_only:
|
||||
rows = json.loads((root/'results'/filename).read_text())
|
||||
else:
|
||||
(root/'bin').mkdir(exist_ok=True)
|
||||
binary = root/'bin/resource-worker.test'
|
||||
subprocess.run(['go','test','-pgo=off','-c','-o',str(binary)],check=True)
|
||||
if args.memory_only:
|
||||
rows = [r for r in json.loads((root/'results'/filename).read_text()) if r['mode'] != 'retained']
|
||||
workloads = [('retained',1),('retained',8)]
|
||||
with tempfile.TemporaryDirectory(prefix='gopeed-resource-') as temp:
|
||||
for extension in ['bilibili','youtube','twitter']:
|
||||
for mode,count in workloads:
|
||||
for repeat in range(args.repeats):
|
||||
engines = ['goja','moejs'] if repeat % 2 == 0 else ['moejs','goja']
|
||||
for engine in engines:
|
||||
output = Path(temp)/'result.json'
|
||||
env = {**os.environ,'GOMAXPROCS':'1','GOGC':'100','GOMEMLIMIT':'off',
|
||||
'GOPEED_RESOURCE_WORKER':'1','RESOURCE_ENGINE':engine,
|
||||
'RESOURCE_EXTENSION':extension,'RESOURCE_MODE':mode,
|
||||
'RESOURCE_COUNT':str(count),'RESOURCE_OUTPUT':str(output)}
|
||||
run = subprocess.run([str(binary),'-test.run=^TestResourceWorker$','-test.timeout=90s'],
|
||||
env=env,text=True,capture_output=True,timeout=100)
|
||||
if run.returncode:
|
||||
raise RuntimeError(run.stdout+run.stderr)
|
||||
row = json.loads(output.read_text())
|
||||
row['repeat'] = repeat
|
||||
rows.append(row)
|
||||
hashes = {r['output_sha256'] for r in rows if r['extension']==extension}
|
||||
if len(hashes)!=1:
|
||||
raise RuntimeError(f'Output mismatch for {extension}: {hashes}')
|
||||
cpu = (row['user_cpu_ns']+row['system_cpu_ns'])/count/1e6
|
||||
print(f'{extension}/{mode}/{count}/{engine} repeat={repeat+1}: '
|
||||
f'CPU={cpu:.3f} ms/op, peakRSS={row["after_work"]["process_peak_rss_bytes"]/2**20:.1f} MiB',flush=True)
|
||||
(root/'results'/filename).write_text(json.dumps(rows,indent=2)+'\n')
|
||||
|
||||
summary = []
|
||||
for extension in ['bilibili','youtube','twitter']:
|
||||
for mode,count in (all_workloads if args.memory_only else workloads):
|
||||
for engine in ['goja','moejs']:
|
||||
group = [r for r in rows if (r['extension'],r['mode'],r['count'],r['engine']) == (extension,mode,count,engine)]
|
||||
if not group:
|
||||
raise RuntimeError(f'Missing samples for {extension}/{mode}/{count}/{engine}')
|
||||
def med(fn): return statistics.median(fn(r) for r in group)
|
||||
cpu = [(r['user_cpu_ns']+r['system_cpu_ns'])/count for r in group]
|
||||
summary.append(dict(extension=extension,mode=mode,count=count,engine=engine,samples=len(group),
|
||||
cpu_ns_per_op=statistics.median(cpu),cpu_ns_min=min(cpu),cpu_ns_max=max(cpu),
|
||||
user_cpu_ns_per_op=med(lambda r:r['user_cpu_ns']/count),
|
||||
system_cpu_ns_per_op=med(lambda r:r['system_cpu_ns']/count),
|
||||
wall_ns_per_op=med(lambda r:r['wall_ns']/count),
|
||||
allocated_bytes_per_op=med(lambda r:r['allocated_bytes']/count),
|
||||
gc_cycles=med(lambda r:r['gc_cycles']),
|
||||
peak_rss_bytes=med(lambda r:r['after_work']['process_peak_rss_bytes']),
|
||||
peak_rss_min_bytes=min(r['after_work']['process_peak_rss_bytes'] for r in group),
|
||||
peak_rss_max_bytes=max(r['after_work']['process_peak_rss_bytes'] for r in group),
|
||||
rss_after_work_bytes=med(lambda r:r['after_work']['rss_bytes']),
|
||||
live_heap_bytes=med(lambda r:r['after_gc']['heap_alloc_bytes']),
|
||||
live_heap_delta_bytes=med(lambda r:r['after_gc']['heap_alloc_bytes']-r['baseline']['heap_alloc_bytes']),
|
||||
retained_rss_bytes=med(lambda r:r['after_os_release']['rss_bytes']),
|
||||
retained_rss_delta_bytes=med(lambda r:r['after_os_release']['rss_bytes']-r['baseline']['rss_bytes']),
|
||||
after_close_heap_delta_bytes=med(lambda r:r['after_close_os_release']['heap_alloc_bytes']-r['baseline']['heap_alloc_bytes']),
|
||||
after_close_rss_bytes=med(lambda r:r['after_close_os_release']['rss_bytes'])))
|
||||
name = 'resources-smoke-summary.json' if args.smoke else 'resources-summary.json'
|
||||
(root/'results'/name).write_text(json.dumps(summary,indent=2)+'\n')
|
||||
Reference in new issue
Block a user