Skip to content

Commit e1bb457

Browse files
committed
Prototype benchmark playground
1 parent 342d1c2 commit e1bb457

2 files changed

Lines changed: 256 additions & 14 deletions

File tree

demo/playground.html

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ <h1>GPU.js - playground : <small style="display:inline-block">GPU Accelerated Ja
3535
This page here, is meant to help "play" with various algorithms, random data sets, etc.<br/>
3636
And benchmark their performance on your computer (CPU vs GPU) respective to the datasize.<br/>
3737
<br/>
38+
[SECURITY WARNING] : This playground here does an "evil" eval on the input funcitons. So obviously do not carlessly copy and paste things here.
39+
<br/><br/>
3840
<a href="https://gpu.rocks">Our main site is found at https://gpu.rocks</a>
3941
<br/><br/>
4042
Enjoy =)
@@ -159,24 +161,24 @@ <h3>Step 3) CPU vs GPU</h3>
159161
</blockquote>
160162
</div>
161163
<div class="container">
162-
<div class="col-sm-3">
163-
<label class="control-label" for="arg_count">Lower bounds</label>
164+
<div class="col-sm-4">
165+
<label class="control-label" for="bench_lower">Lower bounds</label>
164166
<div class="input-group">
165167
<span class="input-group-btn">
166168
<button type="button" class="btn btn-default btn-number" data-type="minus" data-field="bench_lower">
167169
<span class="glyphicon glyphicon-minus"></span>
168170
</button>
169171
</span>
170-
<input type="text" name="bench_lower" id="bench_lower" class="form-control input-number" value="10" min="0" max="4294967295">
172+
<input type="text" name="bench_lower" id="bench_lower" class="form-control input-number" value="100" min="0" max="4294967295">
171173
<span class="input-group-btn">
172174
<button type="button" class="btn btn-default btn-number" data-type="plus" data-field="bench_lower">
173175
<span class="glyphicon glyphicon-plus"></span>
174176
</button>
175177
</span>
176178
</div>
177179
</div>
178-
<div class="col-sm-3">
179-
<label class="control-label" for="arg_count">Upper bounds</label>
180+
<div class="col-sm-4">
181+
<label class="control-label" for="bench_upper">Upper bounds</label>
180182
<div class="input-group">
181183
<span class="input-group-btn">
182184
<button type="button" class="btn btn-default btn-number" data-type="minus" data-field="bench_upper">
@@ -191,38 +193,54 @@ <h3>Step 3) CPU vs GPU</h3>
191193
</span>
192194
</div>
193195
</div>
194-
<div class="col-sm-3">
195-
<label class="control-label" for="arg_count">Increment size</label>
196+
<div class="col-sm-4">
197+
<label class="control-label" for="bench_increment">Increment size</label>
196198
<div class="input-group">
197199
<span class="input-group-btn">
198200
<button type="button" class="btn btn-default btn-number" data-type="minus" data-field="bench_increment">
199201
<span class="glyphicon glyphicon-minus"></span>
200202
</button>
201203
</span>
202-
<input type="text" name="bench_increment" id="bench_increment" class="form-control input-number" value="10" min="0" max="4294967295">
204+
<input type="text" name="bench_increment" id="bench_increment" class="form-control input-number" value="100" min="0" max="4294967295">
203205
<span class="input-group-btn">
204206
<button type="button" class="btn btn-default btn-number" data-type="plus" data-field="bench_increment">
205207
<span class="glyphicon glyphicon-plus"></span>
206208
</button>
207209
</span>
208210
</div>
209211
</div>
210-
<div class="col-sm-3">
212+
<div class="col-sm-4">
211213
<label class="control-label" for="arg_count">Bench Size</label>
212214
<div class="input-group">
213215
<span class="input-group-btn">
214216
<button type="button" class="btn btn-default btn-number" data-type="minus" data-field="bench_size">
215217
<span class="glyphicon glyphicon-minus"></span>
216218
</button>
217219
</span>
218-
<input type="text" name="bench_size" id="bench_size" class="form-control input-number" value="10" min="0" max="4294967295">
220+
<input type="text" name="bench_size" id="bench_size" class="form-control input-number" value="20" min="0" max="4294967295">
219221
<span class="input-group-btn">
220222
<button type="button" class="btn btn-default btn-number" data-type="plus" data-field="bench_size">
221223
<span class="glyphicon glyphicon-plus"></span>
222224
</button>
223225
</span>
224226
</div>
225227
</div>
228+
<div class="col-sm-4">
229+
<label class="control-label" for="arg_count">Warmup Size</label>
230+
<div class="input-group">
231+
<span class="input-group-btn">
232+
<button type="button" class="btn btn-default btn-number" data-type="minus" data-field="warmup_size">
233+
<span class="glyphicon glyphicon-minus"></span>
234+
</button>
235+
</span>
236+
<input type="text" name="bench_size" id="warmup_size" class="form-control input-number" value="5" min="0" max="4294967295">
237+
<span class="input-group-btn">
238+
<button type="button" class="btn btn-default btn-number" data-type="plus" data-field="warmup_size">
239+
<span class="glyphicon glyphicon-plus"></span>
240+
</button>
241+
</span>
242+
</div>
243+
</div>
226244
</div>
227245
<div class="container chartContainer">
228246
<button id="bench_btn" type="button" class="btn btn-primary btn-lg btn-block bench_btn">Run the benchmark!</button>

demo/playground.js

Lines changed: 228 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
11
$(function() {
2+
3+
//-------------------------------------------
4+
//
5+
// Common UI elements setup
6+
//
7+
//-------------------------------------------
8+
9+
/// Setup the various input +/- buttons increments
210
function setupInputNumbers() {
311
//plugin bootstrap minus and plus
412
//http://jsfiddle.net/laelitenetwork/puJ6G/
@@ -75,9 +83,22 @@ $(function() {
7583
});
7684
}
7785

78-
(function updateParamsList() {
86+
//-------------------------------------------
87+
//
88+
// Parameter setup
89+
//
90+
//-------------------------------------------
91+
92+
/// @TODO setup and normalize the parameter list
93+
function updateParamsList() {
7994

80-
})();
95+
}
96+
97+
//-------------------------------------------
98+
//
99+
// Code mirror kernel setup
100+
//
101+
//-------------------------------------------
81102

82103
/// Kernel code mirror object
83104
var CM_kernel = null;
@@ -97,7 +118,17 @@ $(function() {
97118
// Reset the value if needed
98119
var val = CM_kernel.getValue().trim();
99120
if(val.length <= 0) {
100-
CM_kernel.setValue("function kernel(A,B) {\n return (A[this.thread.x] * B[this.thread.x]);\n}")
121+
122+
// The default kernel value
123+
function kernel(A,B) {
124+
var sum = 0;
125+
for (var i=0; i<512; i++) {
126+
sum = (sum*A[this.thread.x] + i)/B[this.thread.x];
127+
}
128+
return sum;
129+
}
130+
131+
CM_kernel.setValue(kernel.toString())
101132
}
102133

103134
// Block edits for first and last line
@@ -111,6 +142,12 @@ $(function() {
111142
$("#kernel_sample_btn").click(updateKernelSampleDisplay);
112143
}
113144

145+
//-------------------------------------------
146+
//
147+
// Kernel arguments / sample preperation
148+
//
149+
//-------------------------------------------
150+
114151
/// Get single argument sample
115152
function getOneKernelArgument(idx, sampleSize) {
116153
var pf = (function(s) {
@@ -136,29 +173,216 @@ $(function() {
136173
return ret;
137174
}
138175

176+
/// Get the kerenel configured dimensions
177+
function getKernelDimensions(sampleSize) {
178+
return [sampleSize];
179+
}
180+
139181
/// Generate the kernel sample result
140182
function getKernelSampleResult(sampleSize) {
141183
var raw = getKernelRawFunction();
142184
var gpu = new GPU();
143185
var ker = gpu.createKernel(raw,{
144-
dimensions : [sampleSize]
186+
dimensions : getKernelDimensions(sampleSize)
145187
});
146188

147189
var args = getKernelArguments(sampleSize);
148190
return ker.apply(ker, args);
149191
}
150192

193+
/// Update the kernel sample results
151194
function updateKernelSampleDisplay() {
152195
// Fixed sample size @TODO implmentation
153196
var res = getKernelSampleResult(10);
154197
console.log("Kernel code sample result : ", res);
155198
$("#kernel_sample").html( JSON.stringify(res) );
156199
}
157200

201+
//-------------------------------------------
202+
//
203+
// Bench marking logic code
204+
//
205+
//-------------------------------------------
206+
207+
/// Run a single benchmark, for the sample size, in a single mode
208+
function singleBenchmark(sampleSize, mode) {
209+
var rawFunction = getKernelRawFunction();
210+
var gpu = new GPU();
211+
var kernel = gpu.createKernel(rawFunction,{
212+
dimensions : getKernelDimensions(sampleSize),
213+
mode : mode
214+
});
215+
216+
var args = getKernelArguments(sampleSize);
217+
var warmup_size = parseInt( $("#warmup_size").val() );
218+
var bench_size = parseInt( $("#bench_size").val() );
219+
220+
// Warmup iteration used to "ignore" optimizers?
221+
for(var w=0; w<warmup_size; ++w) {
222+
kernel.apply(kernel, args);
223+
}
224+
225+
// Benchmark it
226+
var prefObj = window.performance || Date;
227+
var start = prefObj.now();
228+
for(var b=0; b<bench_size; ++b) {
229+
kernel.apply(kernel, args);
230+
}
231+
var end = prefObj.now();
232+
var time = end - start;
233+
return time / parseFloat(bench_size);
234+
}
235+
236+
/// The benchmark charting data, resets on new run
237+
var bench_time_dataSet = {};
238+
var bench_gain_dataSet = {};
239+
240+
/// The various dataset specific arrays
241+
var bench_labels = [];
242+
var bench_gpu_time = [];
243+
var bench_cpu_time = [];
244+
var bench_gain_dif = [];
245+
246+
/// The benchmark charting config,
247+
/// Prettymuch never changing
248+
var bench_time_config = {
249+
referenceValue : 0
250+
}
251+
var bench_gain_config = {
252+
referenceValue : 0
253+
}
254+
255+
/// The chartist object
256+
var bench_time_chartist = null;
257+
var bench_gain_chartist = null;
258+
259+
/// Does a full reset of the benchmark
260+
function resetBenchmarkDataset() {
261+
bench_labels = [];
262+
bench_gpu_time = [];
263+
bench_cpu_time = [];
264+
bench_gain_dif = [];
265+
266+
bench_time_dataSet = {
267+
labels: bench_labels,
268+
series: [
269+
bench_cpu_time,
270+
bench_gpu_time
271+
]
272+
}
273+
bench_gain_dataSet = {
274+
labels: bench_labels,
275+
series: [bench_gain_dif]
276+
}
277+
}
278+
279+
/// Does a dataupdate for the chartist display
280+
function updateBenchmarkDisplay() {
281+
bench_time_chartist.update(bench_time_dataSet);
282+
bench_gain_chartist.update(bench_gain_dataSet);
283+
}
284+
285+
function runCompleteBenchmark() {
286+
var lower_bound = parseInt($("#bench_lower").val());
287+
var upper_bound = parseInt($("#bench_upper").val());
288+
var increment = parseInt($("#bench_increment").val());
289+
290+
var prefObj = window.performance || Date;
291+
var start = prefObj.now();
292+
293+
console.log("Benchmark started! (Lower, Upper, Incre) : ", lower_bound, upper_bound, increment);
294+
resetBenchmarkDataset();
295+
updateBenchmarkDisplay();
296+
297+
function doOneSampleBenchmark(sampleSize, completeCallback) {
298+
var cpu_time = singleBenchmark(sampleSize, "cpu");
299+
var gpu_time = singleBenchmark(sampleSize, "gpu");
300+
var gain_per = 0;
301+
302+
if( cpu_time == gpu_time ) {
303+
gain_per = 0;
304+
} else if( gpu_time < cpu_time ) {
305+
gain_per = cpu_time / gpu_time * 100.0;
306+
} else {
307+
gain_per = -(gpu_time / cpu_time * 100.0);
308+
}
309+
310+
bench_labels.push( sampleSize );
311+
bench_cpu_time.push( cpu_time );
312+
bench_gpu_time.push( gpu_time );
313+
bench_gain_dif.push( gain_per );
314+
315+
bench_time_dataSet.labels = bench_labels;
316+
bench_gain_dataSet.labels = bench_labels;
317+
318+
//console.log( bench_time_dataSet, bench_gain_dataSet );
319+
updateBenchmarkDisplay();
320+
321+
if(completeCallback) {
322+
completeCallback();
323+
}
324+
}
325+
326+
var sampleSize = lower_bound;
327+
328+
function sampleSizeLooper() {
329+
sampleSize += increment;
330+
if(sampleSize < upper_bound) {
331+
// Call after UI update
332+
setTimeout(function(){
333+
doOneSampleBenchmark(sampleSize, sampleSizeLooper);
334+
}, 0);
335+
} else {
336+
updateBenchmarkDisplay();
337+
$("#bench_btn").prop('disabled', false);
338+
339+
var end = prefObj.now();
340+
var time = end - start;
341+
console.log("Benchmark ended! (total time)", time);
342+
console.log("Iteration labels : ", bench_labels);
343+
console.log("Final result for CPU : ", bench_cpu_time);
344+
console.log("Final result for GPU : ", bench_gpu_time);
345+
console.log("Final result for performance gain : ", bench_gain_dif);
346+
347+
window.bench_totalTime = time;
348+
window.bench_labels = bench_labels;
349+
window.bench_cpu_time = bench_cpu_time;
350+
window.bench_gpu_time = bench_gpu_time;
351+
window.bench_gain_dif = bench_gain_dif;
352+
window.bench_time_dataSet = bench_time_dataSet;
353+
window.bench_gain_dataSet = bench_gain_dataSet;
354+
}
355+
}
356+
357+
$("#bench_btn").prop('disabled', true);
358+
doOneSampleBenchmark(sampleSize, sampleSizeLooper);
359+
//updateBenchmarkDisplay();
360+
}
361+
362+
function setupBenchmarking() {
363+
bench_time_chartist = new Chartist.Line('#chart_time', bench_time_dataSet, bench_time_config);
364+
bench_gain_chartist = new Chartist.Line('#chart_gain', bench_gain_dataSet, bench_gain_config);
365+
$("#bench_btn").click(function() {
366+
runCompleteBenchmark();
367+
});
368+
}
369+
370+
//-------------------------------------------
371+
//
372+
// Time to actually do setup calls
373+
//
374+
//-------------------------------------------
375+
158376
// The various setup actual call
159377
setupInputNumbers();
160378
setupKernelEditor();
379+
setupBenchmarking();
161380

162381
window.CM_kernel = CM_kernel;
163382
window.updateKernelSampleDisplay = updateKernelSampleDisplay;
383+
window.singleBenchmark = singleBenchmark;
384+
window.updateBenchmarkDisplay = updateBenchmarkDisplay;
385+
386+
window.bench_time_chartist = bench_time_chartist;
387+
window.bench_gain_chartist = bench_gain_chartist;
164388
});

0 commit comments

Comments
 (0)