]> git.saurik.com Git - apple/libdispatch.git/blob - testing/fast_apply_bench.c
libdispatch-84.5.5.tar.gz
[apple/libdispatch.git] / testing / fast_apply_bench.c
1 #include <mach/mach.h>
2 #include <mach/mach_time.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <assert.h>
6 #include <errno.h>
7 #include <string.h>
8
9 static inline uint64_t
10 rdtsc(void)
11 {
12 uint32_t lo, hi;
13
14 asm volatile("rdtsc" : "=a" (lo), "=d" (hi));
15
16 return (uint64_t)hi << 32 | lo;
17 }
18
19 __attribute__((noinline)) void
20 apply_p(void (^b)(size_t), size_t offset, size_t count)
21 {
22 /* This would feed through to the existing dispatch_apply() */
23 abort();
24 }
25
26 /* a dynamically variable to eventually be added to the kernel/user 'commpage' */
27 size_t total_active_cpus = 8;
28
29 __attribute__((noinline)) void
30 apply(void (^b)(size_t), size_t offset, size_t count)
31 {
32 const size_t too_long = 100000; /* 100 us */
33 const size_t laps = 16;
34 uint64_t delta, tmp, now;
35 size_t i;
36
37 if (total_active_cpus == 1) {
38 for (i = 0; i < count; i++) {
39 b(offset + i);
40 }
41 return;
42 }
43
44 now = mach_absolute_time();
45
46 for (i = 0; i < count; i++) {
47 b(offset + i);
48
49 if (i % laps) {
50 continue;
51 }
52
53 tmp = mach_absolute_time();
54 delta = tmp - now;
55 now = tmp;
56
57 if (delta > (too_long * laps) || (i == 0 && delta > too_long)) {
58 apply_p(b, offset + i + 1, count - (i + 1));
59 return;
60 }
61 }
62 }
63
64 int
65 main(void)
66 {
67 void (^b)(size_t) = ^(size_t index) {
68 asm volatile(""); /* defeat compiler optimizations */
69 };
70 const size_t laps = 10000000;
71 mach_timebase_info_data_t tbi;
72 kern_return_t kr;
73 long double dd;
74 uint64_t s, e;
75 size_t i;
76
77 kr = mach_timebase_info(&tbi);
78 assert(kr == 0);
79 assert(tbi.numer == tbi.denom); /* This will fail on PowerPC. */
80
81 s = mach_absolute_time();
82 for (i = 0; i < laps; i++) {
83 b(i);
84 }
85 e = mach_absolute_time();
86 dd = e - s;
87 dd /= laps;
88 printf("direct:\t%Lf ns\n", dd);
89
90 s = mach_absolute_time();
91 apply(b, 0, laps);
92 e = mach_absolute_time();
93 dd = e - s;
94 dd /= laps;
95 printf("apply:\t%Lf ns\n", dd);
96
97 return 0;
98 }