Skip to content

Commit 7d04c3e

Browse files
authored
Merge pull request #53 from Chessray/eb/ffp-poc
Eb/ffp poc
2 parents 9b7946b + 279e60c commit 7d04c3e

14 files changed

Lines changed: 810 additions & 323 deletions

jmh_full_get_java21.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"benchmark": "GetJNIBenchmark",
3+
"jvmargs": ["Xmx4G", "XX:ErrorFile=./results/hs_err_pid%p.log", "XX:+HeapDumpOnOutOfMemoryError", "-enable-preview"],
4+
"params": {
5+
"valueSize": [10, 50, 512, 1024, 4096, 8192, 16384, 32768, 65536],
6+
"cacheMB": [1],
7+
"checksum": ["none", "copyout"]
8+
},
9+
"options": {
10+
"batchsize": 1,
11+
"warmupiterations": 20,
12+
"warmuptime": "50ms",
13+
"iterations": 50,
14+
"time": "500ms"
15+
},
16+
"result.path": "./results",
17+
"java.library.path": "target/jni-benchmarks-1.0.1-SNAPSHOT-application/jni-benchmarks-1.0.1-SNAPSHOT/lib",
18+
"jar": "target/jni-benchmarks-1.0.1-SNAPSHOT-benchmarks.nar"
19+
}

jmh_full_put_java21.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"benchmark": "PutJNIBenchmark",
3+
"jvmargs": ["Xmx4G", "XX:ErrorFile=./results/hs_err_pid%p.log", "XX:+HeapDumpOnOutOfMemoryError", "-enable-preview"],
4+
"params": {
5+
"valueSize": [10, 50, 512, 1024, 4096, 8192, 16384, 32768, 65536],
6+
"cacheMB": [1],
7+
"checksum": ["none", "copyin"]
8+
},
9+
"options": {
10+
"batchsize": 1,
11+
"warmupiterations": 20,
12+
"warmuptime": "50ms",
13+
"iterations": 50,
14+
"time": "500ms"
15+
},
16+
"result.path": "./results",
17+
"java.library.path": "target/jni-benchmarks-1.0.1-SNAPSHOT-application/jni-benchmarks-1.0.1-SNAPSHOT/lib",
18+
"jar": "target/jni-benchmarks-1.0.1-SNAPSHOT-benchmarks.nar"
19+
}

jmh_plot.json

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,17 @@
55
"name": "valueSize",
66
"min": 1024
77
},
8-
"label": "allbig"
8+
"label": "allbig",
9+
"valueSizeTitle": ">= 1024"
910
},
1011
{
1112
"xaxisparam": {
1213
"name": "valueSize",
1314
"min": 1,
1415
"max": 4096
1516
},
16-
"label": "allsmall"
17+
"label": "allsmall",
18+
"valueSizeTitle": "<= 4096"
1719
# defaults to include_patterns of all matching
1820
},
1921
{
@@ -23,15 +25,17 @@
2325
"max": 4096
2426
},
2527
"exclude_patterns": ["Pooled"],
26-
"label": "nopoolsmall"
28+
"label": "nopoolsmall",
29+
"valueSizeTitle": "<= 4096"
2730
},
2831
{
2932
"xaxisparam": {
3033
"name": "valueSize",
3134
"min": 1024
3235
},
3336
"exclude_patterns": ["Pooled"],
34-
"label": "nopoolbig"
37+
"label": "nopoolbig",
38+
"valueSizeTitle": ">= 1024"
3539
},
3640
{
3741
"xaxisparam": {
@@ -84,4 +88,4 @@
8488
}
8589
],
8690
"result.path": "./analysis/testplots"
87-
}
91+
}

jmh_small_get_java21.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"benchmark": "GetJNIBenchmark",
3+
"jvmargs": ["Xmx4G", "XX:ErrorFile=./results/hs_err_pid%p.log", "XX:+HeapDumpOnOutOfMemoryError", "-enable-preview"],
4+
"params": {
5+
"valueSize": [10, 50, 512, 1024, 4096, 8192, 16384, 32768, 65536],
6+
"cacheMB": [1],
7+
"checksum": ["none", "copyout"]
8+
},
9+
"options": {
10+
"batchsize": 1,
11+
"warmupiterations": 10,
12+
"warmuptime": "20ms",
13+
"iterations": 20,
14+
"time": "200ms"
15+
},
16+
"result.path": "./results",
17+
"java.library.path": "target/jni-benchmarks-1.0.1-SNAPSHOT-application/jni-benchmarks-1.0.1-SNAPSHOT/lib",
18+
"jar": "target/jni-benchmarks-1.0.1-SNAPSHOT-benchmarks.nar"
19+
}

jmh_small_put_java21.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"benchmark": "PutJNIBenchmark",
3+
"jvmargs": ["Xmx4G", "XX:ErrorFile=./results/hs_err_pid%p.log", "XX:+HeapDumpOnOutOfMemoryError", "-enable-preview"],
4+
"params": {
5+
"valueSize": [10, 50, 512, 1024, 4096, 8192, 16384, 32768, 65536],
6+
"cacheMB": [1],
7+
"checksum": ["none", "copyin"]
8+
},
9+
"options": {
10+
"batchsize": 1,
11+
"warmupiterations": 5,
12+
"warmuptime": "20ms",
13+
"iterations": 10,
14+
"time": "100ms"
15+
},
16+
"result.path": "./results",
17+
"java.library.path": "target/jni-benchmarks-1.0.1-SNAPSHOT-application/jni-benchmarks-1.0.1-SNAPSHOT/lib",
18+
"jar": "target/jni-benchmarks-1.0.1-SNAPSHOT-benchmarks.nar"
19+
}

jmh_tiny_get_java21.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"benchmark": "GetJNIBenchmark",
3+
"jvmargs": ["Xmx4G", "XX:ErrorFile=./results/hs_err_pid%p.log", "XX:+HeapDumpOnOutOfMemoryError", "-enable-preview"],
4+
"params": {
5+
"valueSize": [50, 1024, 4096, 16384],
6+
"cacheMB": [1],
7+
"checksum": ["none", "copyout"]
8+
},
9+
"options": {
10+
"batchsize": 1,
11+
"warmupiterations": 5,
12+
"warmuptime": "10ms",
13+
"iterations": 5,
14+
"time": "50ms"
15+
},
16+
"result.path": "./results",
17+
"java.library.path": "target/jni-benchmarks-1.0.1-SNAPSHOT-application/jni-benchmarks-1.0.1-SNAPSHOT/lib",
18+
"jar": "target/jni-benchmarks-1.0.1-SNAPSHOT-benchmarks.nar"
19+
}

jmh_tiny_put_java21.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"benchmark": "PutJNIBenchmark",
3+
"jvmargs": ["Xmx4G", "XX:ErrorFile=./results/hs_err_pid%p.log", "XX:+HeapDumpOnOutOfMemoryError", "-enable-preview"],
4+
"params": {
5+
"valueSize": [50, 1024, 4096, 16384],
6+
"cacheMB": [1],
7+
"checksum": ["none", "copyin"]
8+
},
9+
"options": {
10+
"batchsize": 1,
11+
"warmupiterations": 5,
12+
"warmuptime": "10ms",
13+
"iterations": 5,
14+
"time": "50ms"
15+
},
16+
"result.path": "./results",
17+
"java.library.path": "target/jni-benchmarks-1.0.1-SNAPSHOT-application/jni-benchmarks-1.0.1-SNAPSHOT/lib",
18+
"jar": "target/jni-benchmarks-1.0.1-SNAPSHOT-benchmarks.nar"
19+
}

jmhplot.py

Lines changed: 48 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535

3636
import numpy as np
3737
import matplotlib.pyplot as plt
38+
import matplotlib.ticker as ticker
3839
import pandas as pd
3940
from pandas.core.frame import DataFrame
4041
import re
@@ -193,11 +194,11 @@ def tuple_of_secondary_keys(params: BMParams) -> Tuple:
193194
return tuple(secondaryKeys)
194195

195196

196-
def plot_all_results(params: BMParams, resultSets: ResultSets, path, include_benchmarks: str, exclude_benchmarks: str, label: str) -> None:
197+
def plot_all_results(params: BMParams, xaxisparam:Dict, result_sets: ResultSets, path, include_benchmarks: str, exclude_benchmarks: str, label: str, value_size_title: str, system_info: str) -> None:
197198
indexKeys = tuple_of_secondary_keys(params)
198-
for indexTuple, resultSet in resultSets.items():
199-
plot_result_set(indexKeys, indexTuple, resultSet,
200-
path, include_benchmarks, exclude_benchmarks, label)
199+
for indexTuple, resultSet in result_sets.items():
200+
plot_result_set(xaxisparam, indexKeys, indexTuple, resultSet,
201+
path, include_benchmarks, exclude_benchmarks, label, value_size_title, system_info)
201202

202203

203204
def plot_result_axis_errorbars(ax, resultSet: ResultSet) -> None:
@@ -256,7 +257,7 @@ def plot_result_axis_bars(ax, resultSet: ResultSet) -> None:
256257
bmIndex = bmIndex + 1
257258

258259

259-
def plot_result_set(indexKeys: Tuple, indexTuple: Tuple, resultSet: ResultSet, path: pathlib.Path, include_benchmarks: str, exclude_benchmarks: str, label: str):
260+
def plot_result_set(xaxisparam:Dict, indexKeys: Tuple, indexTuple: Tuple, resultSet: ResultSet, path: pathlib.Path, include_benchmarks: str, exclude_benchmarks: str, label: str, value_size_title: str, system_info: str):
260261
# Determine how many colors we need
261262
num_benchmarks = len(resultSet)
262263

@@ -273,18 +274,24 @@ def plot_result_set(indexKeys: Tuple, indexTuple: Tuple, resultSet: ResultSet, p
273274

274275
plot_result_axis_bars(ax, resultSet)
275276

276-
plt.suptitle("x86_64 - Xeon E5-1650 v3 @ 3.50GHz - 128GB ECC RAM - Ubuntu 24.04.3 LTS - Kernel: 6.14.0-36-generic")
277-
plt.title(
278-
f'{str(indexKeys)}={str(indexTuple)} include={include_benchmarks} exclude={exclude_benchmarks}')
279-
plt.xlabel("# Operations")
277+
# Ensure more marks on the x-axis for log scale
278+
ax.xaxis.set_major_locator(ticker.LogLocator(base=10.0, numticks=15))
279+
ax.xaxis.set_minor_locator(ticker.LogLocator(base=10.0, subs='auto', numticks=15))
280+
ax.xaxis.set_major_formatter(ticker.ScalarFormatter())
281+
ax.xaxis.set_minor_formatter(ticker.NullFormatter())
282+
283+
plt.suptitle(system_info)
284+
title = f'{str(indexKeys)}={str(indexTuple)} include={include_benchmarks} exclude={exclude_benchmarks} Value Size="{value_size_title}"'
285+
plt.title(title)
286+
plt.xlabel(extract_parameter_name(xaxisparam))
280287
plt.ylabel("t (ns)")
281288
plt.legend(loc='upper left', bbox_to_anchor=(1, 1))
282289
plt.grid(visible='True', which='both')
283290

284291
name = f'fig_{"_".join([str(t) for t in indexTuple])}_{label}.png'
285292

286293
if path.is_file():
287-
path = path.parent()
294+
path = path.parent
288295
fig.savefig(path.joinpath(name), bbox_inches='tight')
289296

290297

@@ -322,7 +329,7 @@ def filter_for_benchmarks(dataframe: DataFrame, include_benchmarks, exclude_benc
322329

323330
def filter_for_range(dataframe: DataFrame, xaxisparam: Dict) -> DataFrame:
324331

325-
param_name = required('name', xaxisparam)
332+
param_name = extract_parameter_name(xaxisparam)
326333
xmin = optional('min', xaxisparam, lambda x: int(x))
327334
xmax = optional('max', xaxisparam, lambda x: int(x))
328335
if xmax is None and xmin is None:
@@ -340,6 +347,14 @@ def filter_for_range(dataframe: DataFrame, xaxisparam: Dict) -> DataFrame:
340347
lambda x: int(x) >= xmin and int(x) <= xmax)]
341348

342349

350+
def extract_parameter_name(xaxisparam):
351+
return required('name', xaxisparam)
352+
353+
354+
def default_if_none(optional_string, default_value: str) -> str:
355+
return default_value if optional_string is None else optional_string
356+
357+
343358
def process_some_plots(path: pathlib.Path, plot: Dict) -> None:
344359

345360
xaxisparam = required('xaxisparam', plot)
@@ -348,6 +363,26 @@ def process_some_plots(path: pathlib.Path, plot: Dict) -> None:
348363
include_benchmarks = optional('include_patterns', plot)
349364
exclude_benchmarks = optional('exclude_patterns', plot)
350365
label = required('label', plot)
366+
value_size_title = default_if_none(optional('valueSizeTitle', plot), "All")
367+
368+
# Check for system_info.json in the path
369+
system_info = None
370+
system_info_file = None
371+
if path.is_dir():
372+
system_info_file = path.joinpath('system_info.json')
373+
if path.is_file():
374+
system_info_file = path.parent.joinpath('system_info.json')
375+
376+
if system_info_file and system_info_file.exists():
377+
try:
378+
with system_info_file.open(mode='r', encoding='UTF-8') as f:
379+
info_json = json.load(f)
380+
system_info = info_json.get('system_info')
381+
except Exception:
382+
pass
383+
384+
if system_info is None:
385+
system_info = "System Info unavailable"
351386

352387
dataframe = normalize_data_frame_from_path(path)
353388
if len(dataframe) == 0:
@@ -368,8 +403,8 @@ def process_some_plots(path: pathlib.Path, plot: Dict) -> None:
368403
params: BMParams = split_params(
369404
extract_params(dataframe), primary_param_name)
370405
resultSets = extract_results_per_param(dataframe, params)
371-
plot_all_results(params, resultSets, path,
372-
include_benchmarks, exclude_benchmarks, label)
406+
plot_all_results(params, xaxisparam, resultSets, path,
407+
include_benchmarks, exclude_benchmarks, label, value_size_title, system_info)
373408

374409

375410
def process_benchmarks(config: Dict) -> None:

jmhrun.py

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import pathlib
3333
import json
3434
import subprocess
35+
import platform
3536
from typing import Dict
3637

3738

@@ -112,6 +113,81 @@ def output_options(config: Dict) -> list:
112113
return ['-rff', str(path.joinpath(pathlib.Path(f'jmh_{const_datetime_str}.csv')))]
113114

114115

116+
def get_system_info() -> str:
117+
try:
118+
arch = platform.machine()
119+
system = platform.system()
120+
kernel = platform.release()
121+
122+
cpu_model = ""
123+
ram_info = ""
124+
os_info = ""
125+
java_info = ""
126+
127+
try:
128+
java_version_out = subprocess.check_output(['java', '-version'], stderr=subprocess.STDOUT).decode().strip()
129+
# The first line usually contains the version information
130+
java_info = java_version_out.splitlines()[0]
131+
except Exception:
132+
java_info = "Unknown Java"
133+
134+
if system == "Darwin":
135+
try:
136+
cpu_model = subprocess.check_output(['sysctl', '-n', 'machdep.cpu.brand_string']).decode().strip()
137+
except Exception:
138+
cpu_model = platform.processor()
139+
140+
try:
141+
mem_bytes = int(subprocess.check_output(['sysctl', '-n', 'hw.memsize']).decode().strip())
142+
ram_info = f"{mem_bytes // (1024**3)}GB RAM"
143+
except Exception:
144+
ram_info = "Unknown RAM"
145+
146+
os_info = f"macOS {platform.mac_ver()[0]}"
147+
148+
elif system == "Linux":
149+
try:
150+
with open("/proc/cpuinfo", "r") as f:
151+
for line in f:
152+
if "model name" in line:
153+
cpu_model = line.split(":")[1].strip()
154+
break
155+
except Exception:
156+
cpu_model = platform.processor()
157+
158+
try:
159+
with open("/proc/meminfo", "r") as f:
160+
for line in f:
161+
if "MemTotal" in line:
162+
mem_kb = int(line.split(":")[1].strip().split()[0])
163+
ram_info = f"{mem_kb // (1024**2)}GB RAM"
164+
break
165+
except Exception:
166+
ram_info = "Unknown RAM"
167+
168+
try:
169+
import lsb_release
170+
os_info = lsb_release.get_distro_information()['DESCRIPTION']
171+
except Exception:
172+
try:
173+
with open("/etc/os-release", "r") as f:
174+
for line in f:
175+
if line.startswith("PRETTY_NAME="):
176+
os_info = line.split("=")[1].strip().strip('"')
177+
break
178+
except Exception:
179+
os_info = f"Linux {platform.release()}"
180+
181+
else:
182+
cpu_model = platform.processor()
183+
os_info = f"{system} {platform.release()}"
184+
185+
return f"{arch} - {cpu_model} - {ram_info} - {os_info} - Kernel: {kernel} - {java_info}"
186+
187+
except Exception as e:
188+
return f"Unknown System - {str(e)}"
189+
190+
115191
def build_jmh_command(config: Dict) -> list:
116192

117193
cmd = ["java"]
@@ -192,6 +268,11 @@ def log_jmh_session(cmd: list, config: Dict, config_file: str):
192268
log.writelines(line + '\n' for line in
193269
['```', '#### Command', 'The java command executed to run the tests', '```', ' '.join(cmd), '```'])
194270

271+
# Save system info
272+
system_info_file = output_dir_path(config).joinpath('system_info.json')
273+
with system_info_file.open(mode='w', encoding='UTF-8') as f:
274+
json.dump({"system_info": get_system_info()}, f, indent=4)
275+
195276

196277
def exec_jmh_cmd(cmd: list, help_requested):
197278
cmd_str = ' '.join(cmd)

0 commit comments

Comments
 (0)