fork download
  1. #include <time.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <stdarg.h>
  6.  
  7. const size_t KB=1024, MB=1024*1024, GB=1024*1024*1024;
  8.  
  9. class Test {
  10. void test(size_t size) {
  11. init_timer();
  12. this->size=size;
  13. action(&Test::alloc_data,0,"allocate %.2fGb",(double)size/GB);
  14. action(&Test::seq,size,"init sequential");
  15. action(&Test::run,size,"test sequential ram read");
  16. action(&Test::shuffle,size,"shuffle");
  17. action(&Test::run,size,"test random ram read");
  18. free_data();
  19. }
  20. void seq() {
  21. size_t i,n=get_n();
  22. for(i=0;i<n-1;i++) data[i]=&data[i+1];
  23. data[n-1]=&data[0];
  24. }
  25. void shuffle() {
  26. size_t n=get_n();
  27. for(size_t i=1;i<n;i++) {
  28. size_t j=i+rnd(n-i);
  29. void* t=data[i];data[i]=data[j];data[j]=t;
  30. }
  31. }
  32. void run() {
  33. size_t n=get_n();
  34. void* p=data[0];
  35. for(size_t i=0;i<n;i++) p=*(void**)p;
  36. dummy=p;
  37. }
  38. size_t get_n() { return size/sizeof(void**); }
  39. void alloc_data() { data=(void**)malloc(size); }
  40. void free_data() { free((void*)data); data=0; }
  41. void init_timer() {
  42. if (clock_gettime(CLOCK_REALTIME,t0)) {
  43. fprintf(stderr,"FATAL_ERROR: no realtime clock\n");
  44. }
  45. }
  46. double timer() {
  47. struct timespec ts[1];
  48. clock_gettime(CLOCK_REALTIME,ts);
  49. ts->tv_sec-=t0->tv_sec;
  50. if (ts->tv_nsec<t0->tv_nsec) {
  51. ts->tv_sec--;
  52. ts->tv_nsec=1000000000-t0->tv_nsec+ts->tv_nsec;
  53. } else {
  54. ts->tv_nsec-=t0->tv_nsec;
  55. }
  56. return ts->tv_sec+1e-9*ts->tv_nsec;
  57. }
  58. static size_t rnd(size_t n) {
  59. int s=15; size_t m=0x7FFF;
  60. size_t x=rand()&0x7FFF; m<<=15;
  61. while(m) {
  62. x|=((size_t)(rand()&0x7FFF))<<s;
  63. m<<=15;s+=15;
  64. }
  65. return x%n;
  66. }
  67. void action(void (Test::*fn)(),size_t size,const char *fmt,...) {
  68. va_list v; va_start(v,fmt);
  69. double t1,t2,rate,dt;
  70. vprintf(fmt,v);
  71. t1=timer();
  72. (this->*fn)();
  73. t2=timer();
  74. dt=t2-t1;
  75. if (size!=0) {
  76. rate=dt>0 ? size/dt : 0;
  77. printf(" dt=%.2fms rate=%.1fMb/s\n",dt*1e3,rate/MB);
  78. } else {
  79. printf(" dt=%.2fus\n",dt*1e6);
  80. }
  81. }
  82. void** data; size_t size;
  83. struct timespec t0[1];
  84. volatile void* dummy;
  85. public:
  86. Test(size_t size) { test(size); }
  87. };
  88.  
  89. int main(int argc, char const *argv[]) {
  90. Test(128*MB);
  91. return 0;
  92. }
  93.  
Success #stdin #stdout 3.3s 132576KB
stdin
Standard input is empty
stdout
allocate 0.12Gb dt=3.08us
init sequential dt=17.52ms rate=7305.9Mb/s
test sequential ram read dt=19.07ms rate=6712.6Mb/s
shuffle dt=1952.33ms rate=65.6Mb/s
test random ram read dt=1324.90ms rate=96.6Mb/s