fork(4) download
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <time.h>
  5.  
  6. #define TRIALS 10
  7. #define MAXCOUNT 1000000 // number of doubles to allocate for
  8.  
  9. double * calloc_d(size_t nmemb);
  10. double * calloc_d2(size_t nmemb);
  11.  
  12. int main(void)
  13. {
  14. struct timespec before, after;
  15. double stupidsum = 0.0;
  16. double *dbl_stores[TRIALS];
  17. double *dbl_stores2[TRIALS];
  18. int trials;
  19.  
  20. // Let them warm up
  21. trials = TRIALS;
  22. while(trials--){
  23. dbl_stores[trials] = calloc_d(MAXCOUNT);
  24. dbl_stores2[trials] = calloc_d2(MAXCOUNT);
  25. free(dbl_stores[trials]);
  26. free(dbl_stores2[trials]);
  27. }
  28.  
  29. // Time old code
  30. timespec_get(&before, TIME_UTC);
  31. trials = TRIALS;
  32. while(trials--){
  33. dbl_stores[trials] = calloc_d(MAXCOUNT);
  34. }
  35. timespec_get(&after, TIME_UTC);
  36.  
  37. long dur = (after.tv_sec - before.tv_sec)*1e9 + (after.tv_nsec - before.tv_nsec);
  38. printf("Old code took %ld ns\n", dur);
  39.  
  40. // Time simple code
  41. timespec_get(&before, TIME_UTC);
  42. trials = TRIALS;
  43. while(trials--){
  44. dbl_stores2[trials] = calloc_d2(MAXCOUNT);
  45. }
  46. timespec_get(&after, TIME_UTC);
  47.  
  48. dur = (after.tv_sec - before.tv_sec)*1e9 + (after.tv_nsec - before.tv_nsec);
  49. printf("Simple code took %ld ns\n", dur);
  50.  
  51. trials = TRIALS;
  52. while(trials--){
  53. for(int i = 0; i < MAXCOUNT; ++i){
  54. stupidsum += dbl_stores[trials][i] + dbl_stores2[trials][i];
  55. }
  56. }
  57. printf("print sum to avoid code under test being optimized out: %lf\n", stupidsum);
  58.  
  59. // Yeah I leak the buffers, so sue me. Doesn't affect the benchmark.
  60.  
  61. return 0;
  62. }
  63.  
  64. double * calloc_d2(size_t nmemb)
  65. {
  66. double* ret = malloc(sizeof(double)*nmemb);
  67.  
  68. if(ret){
  69. double* i = ret;
  70. double* end = i + nmemb;
  71. while(i != end){
  72. *i = 0.0;
  73. ++i;
  74. }
  75. }
  76. return ret;
  77. }
  78.  
  79. double * calloc_d(size_t nmemb)
  80. {
  81. double *ret;
  82. double *next; // pointer to beginning of uninitialized segment
  83. size_t alloc_bytes = sizeof(*ret) * nmemb;
  84. size_t init_sz; // size of initialized segment
  85.  
  86. ret = malloc(alloc_bytes);
  87. next = ret;
  88.  
  89. if (ret) {
  90. ret[0] = 0.0;
  91. init_sz = sizeof(*ret);
  92. ++next;
  93.  
  94. while (init_sz < (alloc_bytes + sizeof(*ret)) / 2) {
  95. memmove(next, ret, init_sz);
  96. init_sz *= 2;
  97. next = ret + init_sz / sizeof(*ret);
  98. }
  99. memmove(next, ret, alloc_bytes - init_sz);
  100. }
  101.  
  102. return ret;
  103. }
Success #stdin #stdout 0.14s 158464KB
stdin
Standard input is empty
stdout
Old code took 30588718 ns
Simple code took 28952100 ns
print sum to avoid code under test being optimized out: 0.000000