Skip to content

Commit d196942

Browse files
author
Maxim Egorushkin
committed
Chart styles updated.
1 parent e6dc48a commit d196942

File tree

4 files changed

+123
-331
lines changed

4 files changed

+123
-331
lines changed

html/benchmarks.css

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ h1, h2, h3 {
1111
}
1212

1313
p, li {
14-
color: #A0A0A0;
14+
color: #EEE;
1515
margin-left: 20px;
1616
}
1717

@@ -26,7 +26,7 @@ div.chart {
2626
}
2727

2828
p.copyright {
29-
color: #A0A0A0;
29+
color: #EEE;
3030
font-size: 0.8em;
3131
}
3232

@@ -35,7 +35,7 @@ h1.homepage {
3535
}
3636

3737
p.homepage {
38-
color: #A0A0A0;
38+
color: #EEE;
3939
margin-top: 0em;
4040
font-weight: bold;
4141
}
@@ -55,7 +55,7 @@ svg.arrow-down-circle {
5555
fill: currentColor;
5656
width: 1em;
5757
height: 1em;
58-
color: #A0A0A0;
58+
color: #EEE;
5959
vertical-align: -.1em;
6060
}
6161

html/benchmarks.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
<body>
2626
<h1 class="view-toggle">Scalability Benchmark</h1>
2727
<div>
28-
<p>N producer threads push a 4-byte integer into one same queue, N consumer threads pop the integers from the queue. All producers posts 1,000,000 messages in total. Total time to send and receive all the messages is measured. The benchmark is run for from 1 producer and 1 consumer up to (total-number-of-cpus / 2) producers/consumers to measure the scalabilty of different queues. The minimum, maximum, mean and standard deviation of at least 33 runs are reported in the tooltip.</p>
28+
<p>N producer threads push a 4-byte integer into one same queue, N consumer threads pop the integers from the queue. All producers posts 1,000,000 messages in total. Total time to send and receive all the messages is measured. The benchmark is run for from 1 producer and 1 consumer up to (total-number-of-cpus / 2) producers/consumers to measure the scalabilty of different queues. The minimum, maximum, mean and standard deviation of at least 33 runs are reported in the tooltip, the error bars are ±1 standard deviation.</p>
2929
<h3 class="view-toggle">Scalability on Intel i9-9900KS</h3><div class="chart" id="scalability-9900KS-5GHz"></div>
3030
<h3 class="view-toggle">Scalability on AMD Ryzen 7 5825U</h3><div class="chart" id="scalability-ryzen-5825u"></div>
3131
<h3 class="view-toggle">Scalability on Intel Xeon Gold 6132</h3><div class="chart" id="scalability-xeon-gold-6132"></div>
@@ -34,7 +34,7 @@ <h3 class="view-toggle">Scalability on AMD Ryzen 9 5950X</h3><div class="chart"
3434

3535
<h1 class="view-toggle">Latency Benchmark</h1>
3636
<div>
37-
<p>One thread posts a 4-byte integer to another thread through one queue and waits for a reply from another queue (2 queues in total). The benchmark measures the total time of 100,000 ping-pongs, best of 10 runs. Contention is minimal here (1-producer-1-consumer, 1 element in the queue) to be able to achieve and measure the lowest latency. Reports the average round-trip time, i.e. the time it takes to post a message to another thread and receive a reply. The minimum, maximum, mean and standard deviation of at least 33 runs are reported in the tooltip.</p>
37+
<p>One thread posts a 4-byte integer to another thread through one queue and waits for a reply from another queue (2 queues in total). The benchmark measures the total time of 100,000 ping-pongs, best of 10 runs. Contention is minimal here (1-producer-1-consumer, 1 element in the queue) to be able to achieve and measure the lowest latency. Reports the average round-trip time, i.e. the time it takes to post a message to another thread and receive a reply. The minimum, maximum, mean and standard deviation of at least 33 runs are reported in the tooltip, the error bars are ±1 standard deviation.</p>
3838
<h3 class="view-toggle">Latency on Intel i9-9900KS</h3><div class="chart" id="latency-9900KS-5GHz"></div>
3939
<h3 class="view-toggle">Latency on AMD Ryzen 7 5825U</h3><div class="chart" id="latency-ryzen-5825u"></div>
4040
<h3 class="view-toggle">Latency on Intel Xeon Gold 6132</h3><div class="chart" id="latency-xeon-gold-6132"></div>

html/benchmarks.js

Lines changed: 84 additions & 170 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,13 @@ $(function() {
3535
"OptimistAtomicQueueB2": ['#FFBFBF', 18]
3636
};
3737

38-
function getSeriesColor(s) {
39-
const c = s[0];
40-
return c?.pattern?.color ?? c;
38+
// function getSeriesColor(s) {
39+
// const c = s[0];
40+
// return c?.pattern?.color ?? c;
41+
// }
42+
43+
function fmt(v) {
44+
return Highcharts.numberFormat(v, 0);
4145
}
4246

4347
function plot_scalability(div_id, results, max_lin, max_log) {
@@ -53,29 +57,24 @@ $(function() {
5357
];
5458
let mode = 0;
5559

56-
const columnSeries = Object.entries(results).map(entry => {
57-
const [name, stats] = entry;
60+
const series = [];
61+
for(const [name, stats] of Object.entries(results)) {
5862
const s = settings[name];
59-
return {
63+
series.push({
6064
name: name,
6165
color: s[0],
6266
index: s[1],
6367
type: "column",
6468
data: stats.map(a => [a[0], a[3]]),
6569
atomic_queue_stats: stats,
66-
id: `column-${name}`
67-
}
68-
});
69-
70-
const errorBarSeriesStdev = Object.entries(results).map(entry => {
71-
const [name, stats] = entry;
72-
return {
70+
});
71+
series.push({
7372
name: `${name} StdDev`,
7473
type: 'errorbar',
74+
index: s[1],
7575
data: stats.map(a => [a[0], a[3] - a[4], a[3] + a[4]]),
76-
linkedTo: `column-${name}`
77-
}
78-
});
76+
});
77+
}
7978

8079
const tooltips = [];
8180
const tooltip_formatter = function() {
@@ -86,17 +85,17 @@ $(function() {
8685

8786
const data = [];
8887
for(const p of this.points) {
89-
const stats = p.series.options.atomic_queue_stats[p.point.index];
88+
const [n_threads, min, max, mean, stdev] = p.series.options.atomic_queue_stats[p.point.index].map(fmt);
9089
data[p.series.options.index] = {
9190
name: p.series.name,
9291
color: p.series.color,
93-
min: Highcharts.numberFormat(stats[1], 0),
94-
max: Highcharts.numberFormat(stats[2], 0),
95-
mean: Highcharts.numberFormat(stats[3], 0),
96-
stdev: Highcharts.numberFormat(stats[4], 0)
92+
min: min,
93+
max: max,
94+
mean: mean,
95+
stdev: stdev,
9796
};
9897
}
99-
const tbody = data.reduce((s, d) => d ? s + `<tr><td style="color: ${d.color}">${d.name}: </td><td><strong>${d.mean}</strong></td><td><strong>${d.stdev}</strong></td><td>${d.min}</td><td>${d.max}</td></tr>` : s, "");
98+
const tbody = data.map((d) => `<tr><td style="color: ${d.color}">${d.name}: </td><td><strong>${d.mean}</strong></td><td><strong>${d.stdev}</strong></td><td>${d.min}</td><td>${d.max}</td></tr>`).join('\n')
10099
return tooltips[n_threads] = `
101100
<span class="tooltip_scalability_title">${n_threads} producers, ${n_threads} consumers</span>
102101
<table class="tooltip_scalability">
@@ -107,19 +106,7 @@ $(function() {
107106
};
108107

109108
Highcharts.chart(div_id, {
110-
title: { text: undefined },
111-
series: [...columnSeries, ...errorBarSeriesStdev],
112-
plotOptions: {
113-
errorbar: {
114-
stemWidth: 1,
115-
whiskerLength: 3,
116-
lineWidth: 1,
117-
dashStyle: 'Solid',
118-
enableMouseTracking: false,
119-
showInLegend: false,
120-
color: "#a0a0a0",
121-
}
122-
},
109+
series: series,
123110
chart: {
124111
events: {
125112
click: function() {
@@ -135,163 +122,90 @@ $(function() {
135122
title: { text: 'number of producers, number of consumers' },
136123
tickInterval: 1
137124
},
138-
tooltip: {
139-
followPointer: true,
140-
shared: true,
141-
useHTML: true,
142-
formatter: tooltip_formatter
143-
},
125+
tooltip: { formatter: tooltip_formatter },
144126
});
145127
}
146128

129+
const latencyChartOptions = {
130+
xAxis: {
131+
categories: Object.keys(settings),
132+
labels: { rotation: 0 }
133+
},
134+
yAxis: {
135+
min: 0,
136+
max: 1000,
137+
tickInterval: 100,
138+
title: { text: 'latency, nanoseconds/round-trip' }
139+
},
140+
tooltip: {
141+
formatter: function() {
142+
const [min, max, mean, stdev] = this.series.options.atomic_queue_stats.map(fmt);
143+
return `<strong>mean: ${mean} stdev: ${stdev}</strong> min: ${min} max: ${max}<br/>`;
144+
}
145+
},
146+
};
147147
function plot_latency(div_id, results) {
148-
function createChart(chartType) {
149-
const chartOptions = {
150-
legend: { enabled: true },
151-
xAxis: { categories: Object.keys(results) },
152-
yAxis: { title: { text: 'latency, nanoseconds/round-trip' } },
153-
tooltip: {
154-
followPointer: true,
155-
shared: true,
156-
useHTML: true,
157-
},
158-
};
159-
148+
function chartData(chartType) {
160149
if (chartType === 'boxplot') {
161-
const series = Object.entries(results).map(entry => {
162-
const [name, stats] = entry;
163-
const s = settings[name];
164-
const seriesColor = getSeriesColor(s);
165-
const min = stats[0];
166-
const max = stats[1];
167-
const mean = stats[2];
168-
const stdev = stats[3];
150+
const series = [];
151+
for(const [name, s] of Object.entries(settings)) {
152+
let stats = results[name];
153+
if(!stats)
154+
continue;
155+
const [color, index] = s;
156+
const [min, max, mean, stdev] = stats;
169157
const q1 = mean - stdev;
170158
const q3 = mean + stdev;
171-
172-
return {
159+
series.push({
173160
name: name,
174-
color: seriesColor,
175-
index: s[1],
161+
color: color,
162+
medianColor: color,
176163
type: 'boxplot',
177-
data: [[min, q1, mean, q3, max]],
164+
data: [[index, min, q1, mean, q3, max]],
178165
atomic_queue_stats: stats,
179-
lineColor: seriesColor,
180-
medianColor: seriesColor,
181-
stemColor: seriesColor,
182-
whiskerColor: seriesColor,
183-
};
184-
});
185-
series.sort((a, b) => a.index - b.index);
186-
187-
Highcharts.chart(div_id, $.extend(true, {
166+
});
167+
}
168+
return {
188169
series: series,
189-
plotOptions: {
190-
boxplot: {
191-
fillColor: '#000000',
192-
lineWidth: 2,
193-
medianWidth: 3,
194-
stemDashStyle: 'solid',
195-
stemWidth: 1,
196-
// whiskerLength: '50%',
197-
whiskerWidth: 2
198-
}
199-
},
200170
subtitle: { text: 'click on the chart background to switch to bar chart view' },
201-
title: { text: undefined },
202-
chart: { events: { click: createChart.bind(null, "bar") } },
203-
xAxis: {
204-
labels: {
205-
enabled: false
206-
}
171+
chart: {
172+
inverted: true,
173+
events: { click: createChart.bind(null, "bar") }
207174
},
208-
tooltip: {
209-
formatter: function() {
210-
const data = [];
211-
for (const p of this.points) {
212-
const stats = p.series.options.atomic_queue_stats;
213-
if (!stats) continue;
214-
data[p.series.options.index] = {
215-
name: p.series.name,
216-
color: p.series.color,
217-
min: Highcharts.numberFormat(stats[0], 0),
218-
max: Highcharts.numberFormat(stats[1], 0),
219-
mean: Highcharts.numberFormat(stats[2], 0),
220-
stdev: Highcharts.numberFormat(stats[3], 0)
221-
};
222-
}
223-
const tbody = data.reduce((s, d) => d ? s + `<tr><td style="color: ${d.color}">${d.name}: </td><td><strong>${d.mean}</strong></td><td><strong>${d.stdev}</strong></td><td>${d.min}</td><td>${d.max}</td></tr>` : s, "");
224-
return `
225-
<table class="tooltip_scalability">
226-
<tr><th></th><th>mean</th><th>stdev</th><th>min</th><th>max</th></tr>
227-
${tbody}
228-
</table>`;
229-
}
230-
},
231-
}, chartOptions));
175+
};
232176
} else {
233-
const barSeries = Object.entries(results).map(entry => {
234-
const [name, stats] = entry;
235-
const s = settings[name];
236-
return {
177+
const series = [];
178+
for(const [name, s] of Object.entries(settings)) {
179+
let stats = results[name];
180+
if(!stats)
181+
continue;
182+
const [color, index] = s;
183+
const mean = stats[2];
184+
const stdev = stats[3];
185+
series.push({
237186
name: name,
238-
color: s[0],
239-
index: s[1],
187+
color: color,
240188
type: 'bar',
241-
data: [[s[1], stats[2]]],
189+
data: [[index, mean]],
242190
atomic_queue_stats: stats,
243-
id: `bar-${s[1]}`
244-
};
245-
});
246-
barSeries.sort((a, b) => a.index - b.index);
247-
248-
const errorBarSeriesStdev = barSeries.map(s => {
249-
const stats = s.atomic_queue_stats;
250-
const mean = stats[2];
251-
const stdev = stats[3];
252-
return {
191+
});
192+
series.push({
253193
name: `${s.name} StdDev`,
254194
type: 'errorbar',
255-
data: [[s.index, mean - stdev, mean + stdev]],
256-
linkedTo: s.id
257-
};
258-
});
259-
260-
Highcharts.chart(div_id, $.extend(true, {
261-
series: [...barSeries, ...errorBarSeriesStdev],
262-
plotOptions: {
263-
series: { stacking: 'normal' },
264-
errorbar: {
265-
stemWidth: 1,
266-
whiskerLength: 3,
267-
lineWidth: 1,
268-
dashStyle: 'Solid',
269-
enableMouseTracking: false,
270-
showInLegend: false,
271-
color: "#a0a0a0",
272-
}
273-
},
274-
title: { text: undefined },
195+
data: [[index, mean - stdev, mean + stdev]],
196+
});
197+
}
198+
return {
199+
series: series,
275200
subtitle: { text: 'click on the chart background to switch to boxplot view' },
276201
chart: { events: { click: createChart.bind(null, "boxplot") } },
277-
xAxis: { labels: { rotation: 0 } },
278-
yAxis: {
279-
max: 1000,
280-
tickInterval: 100,
281-
},
282-
tooltip: {
283-
formatter: function() {
284-
const stats = this.series.options.atomic_queue_stats;
285-
const min = Highcharts.numberFormat(stats[0], 0);
286-
const max = Highcharts.numberFormat(stats[1], 0);
287-
const mean = Highcharts.numberFormat(stats[2], 0);
288-
const stdev = Highcharts.numberFormat(stats[3], 0);
289-
return `<strong>mean: ${mean} stdev: ${stdev}</strong> min: ${min} max: ${max}<br/>`;
290-
}
291-
},
292-
}, chartOptions));
202+
};
293203
}
294-
}
204+
};
205+
206+
function createChart(chartType) {
207+
Highcharts.chart(div_id, $.extend(true, chartData(chartType), latencyChartOptions));
208+
};
295209
createChart("bar");
296210
};
297211

0 commit comments

Comments
 (0)