i7 macmini ========== i7 M4 i7 M4 no of words throughput throughput access time access time ----------------------------------------------------------------------------------- 1024 turb 0 1.03e+03 MW/s 1.73e+03 MW/s 0.92 ns/W 0.55 ns/W 2048 turb 0 1e+03 MW/s 7.34e+03 MW/s 0.95 ns/W 0.13 ns/W 4096 turb 0 1.03e+03 MW/s 7.93e+03 MW/s 0.92 ns/W 0.12 ns/W 8192 turb 0 1.01e+03 MW/s 7.75e+03 MW/s 0.94 ns/W 0.12 ns/W 16384 turb 0 1e+03 MW/s 7.82e+03 MW/s 0.95 ns/W 0.12 ns/W 32768 turb 0 999 MW/s 1.41e+03 MW/s 0.95 ns/W 0.68 ns/W 65536 turb 0 992 MW/s 1.41e+03 MW/s 0.96 ns/W 0.68 ns/W 131072 turb 0 989 MW/s 1.43e+03 MW/s 0.96 ns/W 0.67 ns/W 262144 turb 0 901 MW/s 1.5e+03 MW/s 1.06 ns/W 0.64 ns/W 524288 turb 0 979 MW/s 6.01e+03 MW/s 0.97 ns/W 0.16 ns/W 1048576 turb 0 907 MW/s 5.9e+03 MW/s 1.05 ns/W 0.16 ns/W 2097152 turb 0 840 MW/s 5.87e+03 MW/s 1.14 ns/W 0.16 ns/W 4194304 turb 0 841 MW/s 5.7e+03 MW/s 1.13 ns/W 0.17 ns/W 8388608 turb 0 846 MW/s 5.93e+03 MW/s 1.13 ns/W 0.16 ns/W 16777216 turb 0 838 MW/s 6.15e+03 MW/s 1.14 ns/W 0.16 ns/W 33554432 turb 0 834 MW/s 5.93e+03 MW/s 1.14 ns/W 0.16 ns/W Random Access i7 M4 i7 M4 no of words throughput throughput access time access time ------------------------------------------------------------------------------------------ 1024 turb 100 1.04e+03 MW/s 1.47e+03 MW/s 0.91 ns/W 0.65 ns/W 2048 turb 100 1.01e+03 MW/s 1.4e+03 MW/s 0.94 ns/W 0.68 ns/W 4096 turb 100 1.01e+03 MW/s 1.4e+03 MW/s 0.94 ns/W 0.68 ns/W 8192 turb 100 511 MW/s 1.4e+03 MW/s 1.87 ns/W 0.68 ns/W 16384 turb 100 411 MW/s 1.38e+03 MW/s 2.32 ns/W 0.69 ns/W 32768 turb 100 269 MW/s 319 MW/s 3.55 ns/W 2.99 ns/W 65536 turb 100 150 MW/s 252 MW/s 6.37 ns/W 3.78 ns/W 131072 turb 100 110 MW/s 224 MW/s 8.70 ns/W 4.25 ns/W 262144 turb 100 103 MW/s 202 MW/s 9.28 ns/W 4.71 ns/W 524288 turb 100 98.2 MW/s 173 MW/s 9.72 ns/W 5.5 ns/W 1048576 turb 100 77.2 MW/s 141 MW/s 12.4 ns/W 6.76 ns/W 2097152 turb 100 29.9 MW/s 114 MW/s 31.9 ns/W 8.37 ns/W 4194304 turb 100 18.5 MW/s 27.9 MW/s 51.7 ns/W 34.2 ns/W 8388608 turb 100 15.1 MW/s 16.6 MW/s 63.3 ns/W 57.5 ns/W 16777216 turb 100 13.6 MW/s 13.5 MW/s 70.3 ns/W 70.4 ns/W ----------------------------------------------------------------------------------------------- /* -*- Mode: C; -*- * ---------------------------------------------------------------------------- * Title: The True Memory Benchmark * Created: 1999-02-13 15:41 * Author: Gilbert Baumann * ---------------------------------------------------------------------------- * (c) copyright 1999 by Gilbert Baumann */ #include #include #include #include #include #include #include #include #include #define CHECK(x) do{ \ errno=0; \ if(!(x)) { \ fprintf(stderr, "%s:%d: %s failed - %s\n", \ __FILE__, __LINE__, #x, strerror(errno)); \ abort(); \ } }while(0) int default_turb = 200; struct foo { struct foo *p; }; struct foo *setup (int m, int turb) { struct foo *a; CHECK((a = malloc (sizeof (struct foo) * m)) != 0); /* Create initial loop of pointers */ { int i; for (i = 0; i < m-1; i++) a[i].p = a + i + 1; a[i].p = a; } /* Mischen * Wir ziehen immer zwei Zeiger und vertauschen dann innerhalb * der Kette jeweils deren Nachfolger-(Knoten). */ turb = (turb * m) / 100; while (turb--) { /* Ziehe zwei zufaellige Zeiger. */ int i = (rand() % m); int j = (rand() % m); struct foo tmp; /* Nachfolger tauschen */ tmp = a[i]; a[i] = a[j]; a[j] = tmp; /* Nachfolger-Nachfolger tauschen */ tmp = *(a[i].p); *(a[i].p) = *(a[j].p); *(a[j].p) = tmp; } /* all done und raus */ return a; } int verify (struct foo *a) { int i = 0; struct foo *q = a; do{ q = q->p; i++; }while(q != a); return i; } volatile int please_dont_solve_the_halting_problem_for_me; void run_test (int n, struct foo *start) { struct foo *q = start; struct foo *s = start; while (n--) { do{ please_dont_solve_the_halting_problem_for_me += (int)(intptr_t)q; q = q->p; q = q->p; q = q->p; q = q->p; q = q->p; q = q->p; q = q->p; q = q->p; q = q->p; q = q->p; q = q->p; q = q->p; q = q->p; q = q->p; q = q->p; q = q->p; }while(q != s); } } double timeval_to_double (struct timeval *t) { return ((double)(t->tv_sec)) + (1e-6 * ((double)(t->tv_usec))); } static double now (void) { #if 1 static double pivot = 0; struct timeval tv; gettimeofday (&tv, 0); double ti = (double)(tv.tv_sec) + ((double)tv.tv_usec) * 1e-6; if(!pivot) pivot = ti; return ti - pivot; #else return (double)clock() / CLOCKS_PER_SEC; #endif } int usage (char *prg) { fprintf (stderr, "Usage: %s n size[kM] [turb]\n", prg); fprintf (stderr, " n - number of loops.\n"); fprintf (stderr, " size - working set size in *words*\n"); fprintf (stderr, " use 'k' or 'M' for kilo- or mega-words\n"); fprintf (stderr, " turb - turbolence; number of transpositios in percent\n" " of working set size. (default is %d).\n", default_turb); fprintf (stderr, "\n"); exit (1); } void mbench (int nloop, int size, int turb); int turbs[] = { 0, 100, -1 }; int main (int argc, char **argv) { int size = 0; int nloop = 0; int turb = default_turb; struct foo *a; for (int *turb = turbs; *turb >= 0; turb++) { int n = (1 << 17), s = 1; for (int i = 0; i < 16; i++) { mbench(n, s * 1024, *turb); n /= 2; s *= 2; } } return 0; } void mbench (int nloop, int size, int turb) { struct foo *a; a = setup (size, turb); if (verify (a) != size) { fprintf (stderr, "*** Get your program straight and come back then.\n"); exit (1); } { struct rusage r0; struct rusage r1; struct timeval t0; struct timeval t1; double t, wt; double thru, wthru; double accs, waccs; gettimeofday (&t0, 0); getrusage (RUSAGE_SELF, &r0); double ti = now(); run_test (nloop, a); ti = now() - ti; getrusage (RUSAGE_SELF, &r1); gettimeofday (&t1, 0); wt = timeval_to_double(&t1) - timeval_to_double(&t0); t = timeval_to_double(&(r1.ru_utime)) - timeval_to_double(&(r0.ru_utime)); t += timeval_to_double(&(r1.ru_stime)) - timeval_to_double(&(r0.ru_stime)); thru = (double)((nloop * size)) / (t * (double)1024.0 * (double)1024.0); accs = ((double)t * (double)1e9) / ((double)(nloop * size)); wthru = (double)((nloop * size)) / (wt * (double)1024.0 * (double)1024.0); waccs = ((double)wt * (double)1e9) / ((double)(nloop * size)); #if 0 printf ("\n"); printf (" wall u+s unit\n"); printf (" -------------------------------------------\n"); printf (" time %7.3g %7.3g sec \n", wt, t); printf (" thru'put %7.3g %7.3g MW/s \n", wthru, thru); printf (" access time %7.3g %7.3g ns/W \n", waccs, accs); printf ("\n"); printf ("faults: %ld major, %ld minor\n", r1.ru_majflt - r0.ru_majflt, r1.ru_minflt - r0.ru_minflt); #endif printf ("%8d turb %3d %7.3g MW/s %7.3g ns/W\n", size, turb, wthru, waccs); } free(a); }