Guest User

Decay-based count

a guest
Jul 31st, 2017
117
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /* Qratror Labs https://qrator.net/ */
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <stdint.h>
  6. #include <unistd.h>
  7. #include <math.h>
  8.  
  9.  
  10. static inline uint64_t rdtsc(void) {
  11.   union {
  12.     uint64_t tsc_64;
  13.     struct {
  14.       uint32_t lo_32;
  15.       uint32_t hi_32;
  16.     };
  17.   } tsc;
  18.   asm volatile("rdtsc" :
  19.                "=a" (tsc.lo_32),
  20.                "=d" (tsc.hi_32));
  21.   return tsc.tsc_64;
  22. }
  23.  
  24. /* global config and other global stuff */
  25. struct {
  26.   double tau;
  27.   uint64_t tVanish;
  28.   uint16_t *rho_table; /* NB: tau must be no more than (1<<16) */
  29.  
  30. #if !defined(DECAY_MODEL)
  31.   double powers[64];
  32.   double beta_1;
  33. #endif
  34. } g;
  35.  
  36. int ratedet_init(double tau);
  37. void ratedet_finalize();
  38.  
  39. int main(int argc, char **argv) {
  40.   int nIters = 100000000;
  41.   int nRounds = 1;
  42.   switch(argc) {
  43.   case 3:
  44.     nRounds = atoi(argv[2]);
  45.   case 2:
  46.     nIters = atoi(argv[1]);
  47.   case 1:
  48.     break;
  49.   default:
  50.     printf("usage: %s [nIters] [nRounds]\n", argv[0]);
  51.     exit(1);
  52.   }
  53.  
  54.   if(ratedet_init(1<<16))
  55.     exit(1);
  56.  
  57.   printf("tau: %lf", g.tau);
  58. #ifdef DECAY_MODEL
  59.   printf(", tVanish: %lu; %u...%u", g.tVanish, g.rho_table[0], g.rho_table[g.tVanish-1]);
  60. #else
  61. #ifdef MAXDELTA
  62.   printf(", maxDelta: %u, accuracy: %lg", MAXDELTA, exp(-MAXDELTA/g.tau)/g.beta_1);
  63. #else
  64.   printf(", maxDelta: <unused>");
  65. #endif
  66. #endif
  67.   printf("\n");
  68.  
  69.   uint64_t t = rdtsc();
  70.   sleep(1);
  71.   t = rdtsc() - t;
  72.   const double freq = (double)t;
  73.  
  74.   uint64_t minT = ~0UL;
  75.   double sT = 0.;
  76.  
  77.   int iter, round;
  78.   for(round=0; round<nRounds; ++round) {
  79. #ifdef DECAY_MODEL
  80.     uint64_t currTime = g.tVanish;
  81.     uint64_t value = 0;
  82. #else
  83.     uint64_t currTime = 0;
  84.     uint64_t accTime = 0;
  85.     double accValue = 0.;
  86. #endif
  87.     t = rdtsc();
  88.     uint64_t tStep = 1000;
  89.     for(iter=0; iter<nIters; ++iter) {
  90.       /* FIXME: rdtsc() is too slow for this test */
  91. #if 0
  92.       currTime = rdtsc();
  93. #else
  94.       currTime = currTime + tStep;
  95.       tStep = (tStep + 123) & 0xfff;
  96. #endif
  97. #ifdef DECAY_MODEL
  98.       /* update */
  99.       {
  100.         const int64_t dt = labs(value - currTime);
  101.         const int64_t offset = dt > g.tVanish ? g.tVanish : dt;
  102.         const uint64_t maxt = value < currTime ? currTime : value;
  103.         value = maxt + g.rho_table[offset];
  104.       }
  105. #else
  106.       /* update */
  107.       {
  108.         uint64_t delta = currTime - accTime;
  109.         accTime = currTime;
  110.  
  111. #ifdef MAXDELTA
  112.         if(delta >= MAXDELTA)
  113.           {
  114.             accValue = g.beta_1;
  115.           }
  116.         else
  117. #endif
  118.           {
  119.             const double *ppow = g.powers;
  120.             for (; delta != 0; ++ppow, delta >>= 1) {
  121.               if (delta & 1)
  122.                 accValue *= *ppow;
  123.             }
  124.             accValue += g.beta_1;
  125.           }
  126.       }
  127. #endif
  128.     }
  129.     t = rdtsc() - t;
  130.  
  131.     if(0 == round) {
  132.       /* This should be approximately the same for both versions */
  133.       const double total =
  134. #ifdef DECAY_MODEL
  135.         exp((value-currTime)/(double)g.tau)
  136. #else
  137.         accValue/g.beta_1
  138. #endif
  139.         ;
  140.       printf("total value: %lf\n", total);
  141.     }
  142.  
  143.     sT += t;
  144.     if(t < minT) minT = t;
  145.   }
  146.  
  147.   const double meanT = sT/nRounds;
  148.   printf("freq: %g MHz, iter time (best/mean): %lf/%lf cycles, rate (best/mean): %g/%g Miter/s\n",
  149.          freq*1e-6,
  150.          (double)minT/nIters, (double)meanT/nIters,
  151.          freq/(double)minT*nIters*1e-6, freq/(double)meanT*nIters*1e-6);
  152.  
  153.   ratedet_finalize();
  154.   return 0;
  155. }
  156.  
  157. static double rho(double x) {
  158.   return log(1. + exp(-x));
  159. }
  160.  
  161. int ratedet_init(double tau) {
  162.   g.tau = tau;
  163.   g.tVanish = - tau * log(exp(.5/tau) - 1.);
  164.   g.rho_table = (uint16_t*)malloc(g.tVanish * sizeof(uint16_t));
  165.   if(!g.rho_table) return -1;
  166.   uint64_t i;
  167.   for(i=0; i<g.tVanish; ++i)
  168.     g.rho_table[i] = .5 + tau * rho((double)i/tau);
  169.  
  170. #if !defined(DECAY_MODEL)
  171.   const double beta = exp(-1./(double)tau);
  172.   g.beta_1 = 1 - beta;
  173.   double tmp = beta;
  174.   for(i=0; i<64;++i) {
  175.     g.powers[i] = tmp;
  176.     tmp *= tmp;
  177.   }
  178. #endif
  179.  
  180.   return 0;
  181. }
  182.  
  183. void ratedet_finalize() {
  184.   if(g.rho_table)
  185.     free(g.rho_table);
  186. }
RAW Paste Data