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));