]> git.itanic.dy.fi Git - membench/blob - membench.c
Vectorize memory transfers
[membench] / membench.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <sys/time.h>
4
5 #define lsize sizeof(unsigned long)
6
7 long long usec_diff(const struct timeval *a, const struct timeval *b)
8 {
9         long long usec_a, usec_b;
10         usec_a = a->tv_sec * 1000000 + a->tv_usec;
11         usec_b = b->tv_sec * 1000000 + b->tv_usec;
12         return usec_b - usec_a;
13 }
14
15 int main(int argc, char *argv[])
16 {
17         int iterations, j, k, count, size, mask, latcount;
18         unsigned long *buf, i, tmp[8] = {0};
19         struct timeval start, end;
20
21         printf("Benchmark sequential access bandwidth "
22                 "and random access latency\n\n");
23
24         if (argc > 1)
25                 iterations = atoi(argv[1]);
26         else
27                 iterations = 24;
28
29         if (argc > 2)
30                 count = atoi(argv[2]) * 1024;
31         else
32                 count = 1024 * 64;
33         latcount = count / 10;
34
35         printf("Doing %d runs with buffer size goin up to %dk\n",
36                iterations, 1 << (iterations - 10));
37         printf("Running each round %d times\n", count);
38         printf("Size of unsigned long is %d bits\n\n", (int)lsize * 8);
39
40         switch (lsize) {
41         case 4:
42                 j = 12;
43                 break;
44         case 8:
45                 j = 10;
46                 break;
47         default:
48                 printf("WTF?\n");
49                 exit(1);
50         }
51
52         printf("          |"
53                "         Read         |"
54                "         Write        |\n"
55                "          |"
56                "-----------------------"
57                "-----------------------\n"
58                "    Size  |"
59                "    MiB/s         ns  |"
60                "    MiB/s         ns  |\n"
61                "----------|"
62                "-----------------------"
63                "-----------------------\n"
64                 );
65
66         for (; j < iterations + 1; j++) {
67                 size = (1 << j) / lsize;
68                 buf = malloc(size * lsize);
69                 mask = size - 1;
70
71                 if (buf == NULL) {
72                         printf("Malloc failed\n");
73                         exit(1);
74                 }
75
76                 /* Touch the pages */
77                 for (i = 0; i < size; i++)
78                         buf[i] = i;
79
80                 printf("%8dk |", (int)(size * lsize / 1024));
81
82                 /* Read bandwidth*/
83
84                 fflush(stdout);
85
86                 gettimeofday(&start, 0);
87                 for (k = 0; k < count; k++) {
88                         buf[0] = tmp[0];
89                         for (i = 0; i < size; i += 8) {
90                                 tmp[0] += buf[i];
91                                 tmp[1] += buf[i+1];
92                                 tmp[2] += buf[i+2];
93                                 tmp[3] += buf[i+3];
94                                 tmp[4] += buf[i+4];
95                                 tmp[5] += buf[i+5];
96                                 tmp[6] += buf[i+6];
97                                 tmp[7] += buf[i+7];
98                         }
99                 }
100
101                 gettimeofday(&end, 0);
102
103                 printf("% 9.2f  ", (double)(size * lsize) * 
104                        (1000000 / (1024.0 * 1024.0)) * count / 
105                        (double) usec_diff(&start, &end));
106
107                 fflush(stdout);
108
109                 /* Read latency */
110
111                 gettimeofday(&start, 0);
112                 for (k = 0; k < latcount; k++) {
113                         buf[0] = tmp[0];
114                         for (i = 0; i < size; i++)
115                                 tmp[0] += buf[random() & mask];
116                 }
117
118                 gettimeofday(&end, 0);
119
120                 printf("% 9.3f  |", usec_diff(&start, &end) * 1000 / 
121                        ((double) (size * latcount )));
122
123
124                 fflush(stdout);
125
126                 /* Write bandwidth */
127
128                 gettimeofday(&start, 0);
129                 for (k = 0; k < count; k++)
130                         for (i = 0; i < size; i += 8) {
131                                 buf[i  ] = tmp[0];
132                                 buf[i+1] = tmp[1];
133                                 buf[i+2] = tmp[2];
134                                 buf[i+3] = tmp[3];
135                                 buf[i+4] = tmp[4];
136                                 buf[i+5] = tmp[5];
137                                 buf[i+6] = tmp[6];
138                                 buf[i+7] = tmp[7];
139                         }
140                 gettimeofday(&end, 0);
141
142                 printf("% 9.2f  ", (double)(size * lsize) * 
143                        (1000000 / (1024.0 * 1024.0)) * count / 
144                        (double) usec_diff(&start, &end));
145         
146                 fflush(stdout);
147
148                 /* Write latency */
149
150                 gettimeofday(&start, 0);
151                 for (k = 0; k < latcount; k++)
152                         for (i = 0; i < size; i++)
153                                 buf[random() % mask] = i;
154                 gettimeofday(&end, 0);
155
156                 printf("% 9.3f  |", usec_diff(&start, &end) * 1000 / 
157                        ((double) (size * latcount )));
158         
159                 printf("\n");
160
161                 count /= 2;
162                 count = count ? count : 1;
163                 latcount = count / 10;
164                 latcount = latcount ? latcount : 1;
165
166                 free(buf);
167         }
168         return 0;
169 }