Advertisement
Guest User

Get positions of one bits

a guest
Dec 20th, 2013
918
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.53 KB | None | 0 0
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <memory.h>
  4. #include <stdint.h>
  5. #include <math.h>
  6. #include <time.h>
  7. #include <sys/time.h>
  8. #include <assert.h>
  9.  
  10. double dtime() {
  11.     struct timeval mytime;
  12.     gettimeofday(&mytime, (struct timezone *)0);
  13.     return (double)(mytime.tv_sec + mytime.tv_usec*1e-6);
  14. }
  15.  
  16. unsigned char tab0[256*8], tab1[256*8], tab2[256*8], tab3[256*8], tab4[256*8], tab5[256*8];
  17. unsigned char n[256];
  18. int16_t tabofs[256];
  19.  
  20. #define COPY(d, s, n) \
  21. switch(n) { \
  22. case 8: *(d++) = *(s++); \
  23. case 7: *(d++) = *(s++); \
  24. case 6: *(d++) = *(s++); \
  25. case 5: *(d++) = *(s++); \
  26. case 4: *(d++) = *(s++); \
  27. case 3: *(d++) = *(s++); \
  28. case 2: *(d++) = *(s++); \
  29. case 1: *(d++) = *(s++); \
  30. case 0: break;        \
  31. }
  32.  
  33.  
  34. // templated so we can call aggressively unrolled kernels (eventually)
  35. template<unsigned int N, unsigned int K> int enumerate(void) {
  36.     int64_t x, res = 0, tmp, lb, hb, i;
  37.     int64_t end = (1UL << N);
  38.     unsigned char idx[K];
  39.     x = (1UL << K)-1;
  40.     while( x < end ) {
  41.         unsigned char *dst=idx, *src;
  42.         int64_t b, t, c, m, r,z;
  43.         // get the positions of the set bits
  44.         unsigned char zero, one, two, three, four, five;
  45.         zero  =  x & 0x0000000000FFUL;
  46.         one   = (x & 0x00000000FF00UL) >> 8;
  47.         two   = (x & 0x000000FF0000UL) >> 16;
  48.         three = (x & 0x0000FF000000UL) >> 24;
  49.         four  = (x & 0x00FF00000000UL) >> 32;
  50.         five  = (x & 0xFF0000000000UL) >> 40;
  51.         src=tab0+tabofs[zero ]; COPY(dst, src, n[zero ]);
  52.         src=tab1+tabofs[one  ]; COPY(dst, src, n[one  ]);
  53.         src=tab2+tabofs[two  ]; COPY(dst, src, n[two  ]);
  54.         src=tab3+tabofs[three]; COPY(dst, src, n[three]);
  55.         src=tab4+tabofs[four ]; COPY(dst, src, n[four ]);
  56.         src=tab5+tabofs[five ]; COPY(dst, src, n[five ]);
  57.  
  58.         // TODO: add code to actually use idx here :)
  59.    
  60.         // advance to next integer with K bits set in N
  61.         b = x & -x;
  62.         t = x + b;
  63.         c = x^t;
  64.         z = __builtin_ctz(x);
  65.         m = c >> 2+z;
  66.         x = t|m;
  67.         // add a model
  68.         res++;
  69.     }
  70.     return res;
  71. }
  72.  
  73. int main(void) {
  74.     // set up the tables
  75.     int ofs=0;
  76.     for(int i=0; i<256; i++) {
  77.         unsigned char tmp=i, lb;
  78.         n[i] = 0;
  79.         tabofs[i] = ofs;
  80.         while( tmp ) {
  81.             tab0[ofs] = __builtin_ctz(tmp);
  82.             tab1[ofs] = tab0[ofs]+8;
  83.             tab2[ofs] = tab0[ofs]+16;
  84.             tab3[ofs] = tab0[ofs]+24;
  85.             tab4[ofs] = tab0[ofs]+32;
  86.             tab5[ofs] = tab0[ofs]+40;
  87.             ofs++;
  88.             lb = tmp & -tmp;
  89.             tmp ^= lb;
  90.             n[i]++;
  91.         }
  92.     }
  93.     double start = dtime();
  94.     int64_t n = enumerate<40,10>();  // get the indices of all numbers with 10 out of 40 bits set
  95.     printf("%i models took %.2f seconds\n", n, (dtime()-start));
  96.     return 0;
  97. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement