... |
... |
@@ -267,29 +267,19 @@ int compare(const void* a, const void* b) { |
267
|
267
|
if (*(double*)a < *(double*)b) return -1;
|
268
|
268
|
return 0;
|
269
|
269
|
}
|
270
|
|
- /*
|
271
|
|
- * Bench code
|
272
|
|
- */
|
273
|
270
|
|
|
271
|
+static void benchmark(FT_Face face, btest_t* test, int max_iter, double max_time, double warmup) {
|
|
272
|
+ int n, done;
|
|
273
|
+ int total_done = 0; // track total iterations done across all chunks
|
|
274
|
+ btimer_t timer, elapsed;
|
274
|
275
|
|
275
|
|
- static void
|
276
|
|
- benchmark( FT_Face face,
|
277
|
|
- btest_t* test,
|
278
|
|
- int max_iter,
|
279
|
|
- double max_time,
|
280
|
|
- double warmup )
|
281
|
|
- {
|
282
|
|
-
|
283
|
|
- int n, done;
|
284
|
|
- btimer_t timer, elapsed;
|
285
|
|
-
|
286
|
276
|
int NUM_CHUNKS = max_iter / CHUNK_SIZE;
|
287
|
|
- double results[NUM_CHUNKS];
|
|
277
|
+ double medians[NUM_CHUNKS];
|
|
278
|
+ double errors[NUM_CHUNKS];
|
288
|
279
|
|
289
|
|
- if ( test->cache_first )
|
290
|
|
- {
|
291
|
|
- TIMER_RESET( &timer );
|
292
|
|
- test->bench( &timer, face, test->user_data );
|
|
280
|
+ if (test->cache_first) {
|
|
281
|
+ TIMER_RESET(&timer);
|
|
282
|
+ test->bench(&timer, face, test->user_data);
|
293
|
283
|
}
|
294
|
284
|
|
295
|
285
|
// Initial warm-up
|
... |
... |
@@ -297,56 +287,47 @@ int compare(const void* a, const void* b) { |
297
|
287
|
test->bench(&timer, face, test->user_data);
|
298
|
288
|
}
|
299
|
289
|
|
300
|
|
- printf( " %-25s ", test->title );
|
301
|
|
- fflush( stdout );
|
302
|
|
-
|
|
290
|
+ printf(" %-25s ", test->title);
|
|
291
|
+ fflush(stdout);
|
303
|
292
|
|
304
|
293
|
for (int chunk = 0; chunk < NUM_CHUNKS; chunk++) {
|
305
|
|
- TIMER_RESET( &timer );
|
306
|
|
- TIMER_RESET( &elapsed );
|
|
294
|
+ double chunk_results[CHUNK_SIZE];
|
|
295
|
+ TIMER_RESET(&timer);
|
|
296
|
+ TIMER_RESET(&elapsed);
|
307
|
297
|
|
308
|
298
|
// Execute a chunk of iterations
|
309
|
299
|
for (n = 0, done = 0; n < CHUNK_SIZE; n++) {
|
310
|
|
- TIMER_START( &elapsed );
|
311
|
|
- done += test->bench( &timer, face, test->user_data );
|
312
|
|
- TIMER_STOP( &elapsed );
|
313
|
|
-
|
314
|
|
-
|
|
300
|
+ TIMER_START(&elapsed);
|
|
301
|
+ done += test->bench(&timer, face, test->user_data);
|
|
302
|
+ TIMER_STOP(&elapsed);
|
|
303
|
+ chunk_results[n] = TIMER_GET(&elapsed);
|
|
304
|
+
|
|
305
|
+ // Check max_time for each iteration, break if exceeded
|
|
306
|
+ if (TIMER_GET(&elapsed) > 1E6 * max_time) {
|
|
307
|
+ break;
|
|
308
|
+ }
|
315
|
309
|
}
|
316
|
|
- if (TIMER_GET( &elapsed ) > 1E6 * max_time) {
|
317
|
|
- //break;
|
318
|
|
- }
|
319
|
|
- results[chunk] = TIMER_GET( &timer );
|
320
|
|
- }
|
|
310
|
+ total_done += done;
|
321
|
311
|
|
322
|
|
- // Sort results for IQR calculation
|
323
|
|
- qsort(results, NUM_CHUNKS, sizeof(double), compare);
|
324
|
|
-
|
325
|
|
- double q1 = results[NUM_CHUNKS / 4];
|
326
|
|
- double q3 = results[3 * NUM_CHUNKS / 4];
|
327
|
|
- double iqr = q3 - q1;
|
328
|
|
- double lower_bound = q1 - 1.5 * iqr;
|
329
|
|
- double upper_bound = q3 + 1.5 * iqr;
|
330
|
|
-
|
331
|
|
- double total_time = 0.0;
|
332
|
|
- int valid_chunks = 0;
|
333
|
|
-
|
334
|
|
- for (int chunk = 0; chunk < NUM_CHUNKS; chunk++) {
|
335
|
|
- if (results[chunk] >= lower_bound && results[chunk] <= upper_bound) {
|
336
|
|
- total_time += results[chunk];
|
337
|
|
- valid_chunks++;
|
|
312
|
+ qsort(chunk_results, CHUNK_SIZE, sizeof(double), compare);
|
|
313
|
+ if (CHUNK_SIZE % 2 == 0) {
|
|
314
|
+ medians[chunk] = (chunk_results[CHUNK_SIZE / 2 - 1] + chunk_results[CHUNK_SIZE / 2]) / 2.0;
|
|
315
|
+ } else {
|
|
316
|
+ medians[chunk] = chunk_results[CHUNK_SIZE / 2];
|
338
|
317
|
}
|
|
318
|
+ errors[chunk] = chunk_results[91 * CHUNK_SIZE / 100] - chunk_results[10 * CHUNK_SIZE / 100];
|
339
|
319
|
}
|
340
|
320
|
|
341
|
|
- double average_time = total_time / valid_chunks;
|
342
|
|
-
|
343
|
|
-
|
|
321
|
+ qsort(medians, NUM_CHUNKS, sizeof(double), compare);
|
|
322
|
+ double final_median;
|
|
323
|
+ if (NUM_CHUNKS % 2 == 0) {
|
|
324
|
+ final_median = (medians[NUM_CHUNKS / 2 - 1] + medians[NUM_CHUNKS / 2]) / 2.0;
|
|
325
|
+ } else {
|
|
326
|
+ final_median = medians[NUM_CHUNKS / 2];
|
|
327
|
+ }
|
344
|
328
|
|
345
|
|
- printf( "%10.1f microseconds %10d done\n",
|
346
|
|
- average_time, done );
|
347
|
|
-
|
348
|
|
- }
|
349
|
|
-
|
|
329
|
+ printf("%10.1f microseconds %10d done\n", final_median, total_done);
|
|
330
|
+}
|
350
|
331
|
|
351
|
332
|
/*
|
352
|
333
|
* Various tests
|