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