+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/time.h>
+
+#define lsize sizeof(unsigned long)
+
+long usec_diff(const struct timeval *a, const struct timeval *b)
+{
+ long usec_a, usec_b;
+ usec_a = a->tv_sec * 1000000 + a->tv_usec;
+ usec_b = b->tv_sec * 1000000 + b->tv_usec;
+ return usec_b - usec_a;
+}
+
+int main(int argc, char *argv[])
+{
+ int iterations, j, k, count, size;
+ unsigned long *buf, i, tmp = 0;
+ struct timeval start, end;
+
+ if (argc > 1)
+ iterations = atoi(argv[1]);
+ else
+ iterations = 24;
+
+ if (argc > 2)
+ count = atoi(argv[2]) * 1024;
+ else
+ count = 1024;
+
+ printf("Doing %d runs with buffer size goin up to %dk\n",
+ iterations, 1 << (iterations - 10));
+ printf("Running each round %d times\n", count);
+ printf("Size of unsigned long is %lu bits\n", lsize * 8);
+
+ switch (lsize) {
+ case 4:
+ j = 12;
+ break;
+ case 8:
+ j = 10;
+ break;
+ default:
+ printf("WTF?\n");
+ exit(1);
+ }
+
+ for (; j < iterations + 1; j++) {
+ size = (1 << j) / lsize;
+ buf = malloc(size * lsize);
+
+ if (buf == NULL) {
+ printf("Malloc failed\n");
+ exit(1);
+ }
+
+ /* Touch the pages */
+ for (i = 0; i < size; i++)
+ buf[i] = i;
+
+ printf("%luk\t", size * lsize / 1024);
+
+ printf("read: ");
+ fflush(stdout);
+
+ gettimeofday(&start, 0);
+ for (k = 0; k < count; k++) {
+ buf[0] = tmp;
+ for (i = 0; i < size; i++)
+ tmp += buf[i];
+ }
+
+ gettimeofday(&end, 0);
+
+ printf("% 9.2f MB/s ", (double)(size * lsize) *
+ (1000000 / (1024.0 * 1024.0)) * count /
+ (double) usec_diff(&start, &end));
+
+
+ printf("write: ");
+ fflush(stdout);
+
+ gettimeofday(&start, 0);
+ for (k = 0; k < count; k++)
+ for (i = 0; i < size; i++)
+ buf[i] = i;
+ gettimeofday(&end, 0);
+
+ printf("% 9.2f MB/s ", (double)(size * lsize) *
+ (1000000 / (1024.0 * 1024.0)) * count /
+ (double) usec_diff(&start, &end));
+
+ printf("\n");
+
+ free(buf);
+ }
+ return 0;
+}