]> git.saurik.com Git - apple/libdispatch.git/blob - testing/yet-another-apply-test.c
libdispatch-84.5.5.tar.gz
[apple/libdispatch.git] / testing / yet-another-apply-test.c
1 #include <dispatch/dispatch.h>
2 #include <sys/stat.h>
3 #include <sys/mman.h>
4 #include <mach/mach.h>
5 #include <mach/mach_time.h>
6 #include <stdlib.h>
7 #include <stdio.h>
8 #include <fcntl.h>
9 #include <assert.h>
10
11 static uint64_t total;
12
13 #define LAPS (256 * 1024 * 1024)
14 #define SIZE (LAPS * sizeof(int))
15
16 int
17 main(int argc, char *argv[])
18 {
19 dispatch_queue_t cq = dispatch_get_concurrent_queue(0);
20 struct stat sb;
21 long double cycles;
22 uint64_t s, e, d;
23 uint64_t tmp_total;
24 int r, fd;
25 const int *nums;
26 size_t i, stride;
27
28 if (argc != 2) {
29 fprintf(stderr, "usage: %s <file>\n", argv[0]);
30 exit(EXIT_FAILURE);
31 }
32
33 // make sure to have 2GB + of RAM installed and run this before hand:
34 // dd if=/dev/random bs=1024k count=1024 of=/tmp/testfile
35 fd = open(argv[1], O_RDONLY);
36 assert(fd != -1);
37
38 r = fstat(fd, &sb);
39 assert(r != -1);
40 assert(sb.st_size >= (off_t)SIZE);
41
42 nums = mmap(NULL, SIZE, PROT_READ, MAP_FILE|MAP_PRIVATE, fd, 0);
43 assert(nums != MAP_FAILED);
44
45 // force pages to be faulted in
46 for (i = 0; i < LAPS; i++) {
47 total += nums[i];
48 }
49
50 for (stride = 1; stride < (LAPS + 1); stride <<= 1) {
51 total = 0;
52 s = mach_absolute_time();
53 dispatch_apply(LAPS / stride, cq, ^(size_t idx) {
54 const int *nums2 = nums + (idx * stride);
55 uint64_t ptotal = 0;
56 size_t idx2 = 0;
57
58 // assert(stride > 0);
59 do {
60 ptotal += nums2[idx2++];
61 } while (idx2 < stride);
62
63 __sync_fetch_and_add(&total, ptotal);
64 });
65 e = mach_absolute_time();
66 d = e - s;
67 cycles = d;
68 cycles /= LAPS;
69 printf("da%lu:\t%Lf ns\n", stride, cycles);
70 }
71
72 tmp_total = 0;
73 total = 0;
74 s = mach_absolute_time();
75 for (i = 0; i < LAPS; i++) {
76 tmp_total += nums[i];
77 }
78 total = tmp_total;
79 e = mach_absolute_time();
80 d = e - s;
81 cycles = d;
82 cycles /= LAPS;
83 printf("naïve:\t%Lf ns\n", cycles);
84
85
86 tmp_total = 0;
87 total = 0;
88 s = mach_absolute_time();
89 #pragma omp parallel for reduction(+:tmp_total)
90 for (i = 0; i < LAPS; i++) {
91 tmp_total += nums[i];
92 }
93 total = tmp_total;
94 e = mach_absolute_time();
95 d = e - s;
96 cycles = d;
97 cycles /= LAPS;
98 printf("OpenMP:\t%Lf ns\n", cycles);
99
100 exit(EXIT_SUCCESS);
101 }