4 * (c)Copyright 2003 Matthew Dillon. This code is hereby placed in the public
7 * Attempt to figure out the L1 and L2 cache sizes and measure memory
8 * bandwidth for the L1 and L2 cache and for non-cache memory.
10 * $DragonFly: src/test/sysperf/mbwtest.c,v 1.1 2003/11/13 07:10:36 dillon Exp $
19 #define MAXBYTES (16*1024*1024)
21 static int bandwidth_test(char *buf, int loops, int bytes, char *msg);
22 static void start_timing(void);
23 static int stop_timing(char *str, long long bytes);
26 main(int ac, char **av)
39 buf = malloc(MAXBYTES * 2);
40 bzero(buf, MAXBYTES * 2);
43 * Get a baseline for 1/4 second L1 cache timing maximizing the number
44 * of loops. The minimum L1 cache size is 4K.
47 us1 = bandwidth_test(buf, 1000, 4096, NULL); /* uS per 1000 loops */
48 loops = 1000000LL * 1000 / 4 / us1; /* loops for 1/4 sec */
49 count1 = loops * 4096LL;
51 us1 = bandwidth_test(buf, loops, 4096, NULL); /* best case timing */
52 printf("."); fflush(stdout); usleep(1000000 / 4);
55 * Search for the L1 cache size. Look for a 20% difference in bandwidth
59 us1 = bandwidth_test(buf, count1 / 4096 + 20, 4096, NULL);
60 for (bytes1 = 8192; bytes1 < MAXBYTES; bytes1 <<= 1) {
62 us2 = bandwidth_test(buf, count1 / bytes1 + 20, bytes1, NULL);
63 if (us2 > us1 + us1 / 5)
66 bytes1 >>= 1; /* actual L1 cache size */
67 count2 = count1 * us1 / us2;
68 printf("."); fflush(stdout); usleep(1000000 / 4);
73 us1 = bandwidth_test(buf, count2 / bytes2 + 20, bytes2, NULL);
74 for (bytes2 <<= 1; bytes2 < MAXBYTES; bytes2 <<= 1) {
76 us2 = bandwidth_test(buf, count2 / bytes2 + 20, bytes2, NULL);
77 if (us2 > us1 + us1 / 5)
80 count3 = count2 * us1 / us2;
81 bytes2 >>= 1; /* actual L2 cache size */
84 * Final run to generate output
86 printf("\nL1 cache size: %d\n", bytes1);
87 if (bytes2 == MAXBYTES)
88 printf("L2 cache size: No L2 cache found\n");
90 printf("L2 cache size: %d\n", bytes2);
93 bandwidth_test(buf, count1 / bytes1 + 20, bytes1, "L1 cache bandwidth");
94 if (bytes2 != MAXBYTES) {
96 bandwidth_test(buf, count2 / bytes2 + 20, bytes2,
97 "L2 cache bandwidth");
101 * Set bytes2 to exceed the L2 cache size
104 if (bytes2 < MAXBYTES)
107 bandwidth_test(buf, count3 / bytes2 + 20, bytes2, "non-cache bandwidth");
116 bandwidth_test(char *buf, int loops, int bytes, char *msg)
125 for (j = 0; j < loops; ++j) {
126 for (bptr = buf; bptr < lptr; bptr += 32) {
127 v = *(volatile int *)(bptr + 0);
128 v = *(volatile int *)(bptr + 4);
129 v = *(volatile int *)(bptr + 8);
130 v = *(volatile int *)(bptr + 12);
131 v = *(volatile int *)(bptr + 16);
132 v = *(volatile int *)(bptr + 20);
133 v = *(volatile int *)(bptr + 24);
134 v = *(volatile int *)(bptr + 28);
137 us = stop_timing(msg, (long long)bytes * loops);
145 gettimeofday(&tv1, NULL);
150 stop_timing(char *str, long long bytes)
154 gettimeofday(&tv2, NULL);
156 us = tv2.tv_usec + 1000000 - tv1.tv_usec +
157 (tv2.tv_sec - tv1.tv_sec - 1) * 1000000;
159 printf("%s: %4.2f Mbytes/sec\n",
161 (double)bytes * 1000000.0 / ((double)us * 1024.0 * 1024.0));