#include <sys/file.h>
#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#define MAXBYTES (16*1024*1024)
static int bandwidth_test(char *buf, int loops, int bytes, char *msg);
static void start_timing(void);
static int stop_timing(char *str, long long bytes);
int
main(int ac, char **av)
{
char *buf;
int loops;
int us1;
int us2;
long long count1;
long long count2;
long long count3;
long long count4;
int bytes1;
int bytes2;
int bytes3;
int bytes4;
buf = malloc(MAXBYTES * 2);
bzero(buf, MAXBYTES * 2);
start_timing();
us1 = bandwidth_test(buf, 1000, 4096, NULL);
loops = 1000000LL * 1000 / 4 / us1;
count1 = loops * 4096LL;
start_timing();
us1 = bandwidth_test(buf, loops, 4096, NULL);
printf("."); fflush(stdout); usleep(1000000 / 4);
bzero(buf, 4096);
start_timing();
us1 = bandwidth_test(buf, count1 / 4096 + 20, 4096, NULL);
for (bytes1 = 8192; bytes1 < MAXBYTES; bytes1 <<= 1) {
start_timing();
us2 = bandwidth_test(buf, count1 / bytes1 + 20, bytes1, NULL);
if (us2 > us1 + us1 / 5)
break;
}
bytes1 >>= 1;
count2 = count1 * us1 / us2;
printf("."); fflush(stdout); usleep(1000000 / 4);
bytes2 = bytes1 << 1;
bzero(buf, bytes2);
start_timing();
us1 = bandwidth_test(buf, count2 / bytes2 + 20, bytes2, NULL);
for (bytes2 <<= 1; bytes2 < MAXBYTES; bytes2 <<= 1) {
start_timing();
us2 = bandwidth_test(buf, count2 / bytes2 + 20, bytes2, NULL);
if (us2 > us1 + us1 / 5)
break;
}
count3 = count2 * us1 / us2;
bytes2 >>= 1;
bytes3 = bytes2 << 1;
bzero(buf, bytes3);
start_timing();
us1 = bandwidth_test(buf, count3 / bytes3 + 20, bytes3, NULL);
for (bytes3 <<= 1; bytes3 < MAXBYTES; bytes3 <<= 1) {
start_timing();
us2 = bandwidth_test(buf, count3 / bytes3 + 20, bytes3, NULL);
if (us2 > us1 + us1 / 5)
break;
}
count4 = count3 * us1 / us2;
bytes3 >>= 1;
printf("\nL1 cache size: %d\n", bytes1);
if (bytes2 == MAXBYTES)
printf("L2 cache size: No L2 cache found\n");
else
printf("L2 cache size: %d\n", bytes2);
if (bytes3 == MAXBYTES)
printf("L3 cache size: No L3 cache found\n");
else
printf("L3 cache size: %d\n", bytes3);
sleep(1);
start_timing();
bandwidth_test(buf, count1 / bytes1 + 20, bytes1, "L1 cache bandwidth");
if (bytes2 != MAXBYTES) {
start_timing();
bandwidth_test(buf, count2 / bytes2 + 20, bytes2,
"L2 cache bandwidth");
}
if (bytes3 != MAXBYTES) {
start_timing();
bandwidth_test(buf, count3 / bytes3 + 20, bytes3,
"L3 cache bandwidth");
}
bytes4 = bytes3 << 1;
if (bytes4 < MAXBYTES)
bytes4 <<= 1;
start_timing();
bandwidth_test(buf, count4 / bytes4 + 20, bytes4, "non-cache bandwidth");
return(0);
}
struct timeval tv1;
struct timeval tv2;
static
int
bandwidth_test(char *buf, int loops, int bytes, char *msg)
{
register char *bptr;
register char *lptr;
register int v;
int j;
int us;
lptr = buf + bytes;
for (j = 0; j < loops; ++j) {
for (bptr = buf; bptr < lptr; bptr += 32) {
v = *(volatile int *)(bptr + 0);
v = *(volatile int *)(bptr + 4);
v = *(volatile int *)(bptr + 8);
v = *(volatile int *)(bptr + 12);
v = *(volatile int *)(bptr + 16);
v = *(volatile int *)(bptr + 20);
v = *(volatile int *)(bptr + 24);
v = *(volatile int *)(bptr + 28);
}
}
us = stop_timing(msg, (long long)bytes * loops);
return(us);
}
static
void
start_timing(void)
{
gettimeofday(&tv1, NULL);
}
static
int
stop_timing(char *str, long long bytes)
{
int us;
gettimeofday(&tv2, NULL);
us = tv2.tv_usec + 1000000 - tv1.tv_usec +
(tv2.tv_sec - tv1.tv_sec - 1) * 1000000;
if (str) {
printf("%s: %4.2f Mbytes/sec\n",
str,
(double)bytes * 1000000.0 / ((double)us * 1024.0 * 1024.0));
}
return(us);
}