Advertisement
dlemire

bitmapslow.cpp

Feb 23rd, 2012
129
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.64 KB | None | 0 0
  1. /**
  2. *
  3. * Daniel Lemire, February 2012, http://lemire.me/
  4. *
  5. * Suppose that you want to copy an array over
  6. * another, except for some exceptions.
  7. * What is faster?
  8. *
  9. *  g++ -Ofast bitmapslow bitmapslow.cpp
  10.  
  11. *
  12. * Published on blog.
  13. */
  14.  
  15.  
  16. #include <iostream>
  17. #include <vector>
  18. #include <cstdlib>
  19. #include <cstring>
  20. #include <sys/stat.h>
  21. #include <sys/time.h>
  22. #include <sys/types.h>
  23.  
  24. using namespace std;
  25.  
  26. typedef unsigned int uint;
  27. typedef unsigned char byte;
  28.  
  29.  
  30.  
  31.  
  32. class ZTimer
  33. {
  34. public:
  35.     struct timeval t1, t2;
  36. public:
  37.     ZTimer() :  t1(), t2() { gettimeofday(&t1,0); t2 = t1; }
  38.     void reset() {gettimeofday(&t1,0); t2 = t1;}
  39.     int elapsed() { return ((t2.tv_sec - t1.tv_sec) * 1000) + ((t2.tv_usec - t1.
  40. tv_usec) / 1000); }
  41.     int split() { gettimeofday(&t2,0); return elapsed(); }
  42. };
  43.  
  44.  
  45. /**
  46. * This copies the data from begin to end. We write to "out".
  47. */
  48. __attribute__ ((noinline)) void justcopy(const uint * const  __restrict__ begin,
  49.         const uint * const  end,
  50.     uint * __restrict__ out) {
  51.     for(const uint *  __restrict__ i = begin; i!=end;++i) {
  52.         *(out++) = *i;
  53.     }
  54.     /* we could use this instead of the previous loop, but it is no faster:
  55.      memcpy ( out, begin, (end-begin)*sizeof(uint) );
  56.      at least under gcc 4.6
  57.     */
  58. }
  59.  
  60. /**
  61. * This copies the data from begin to end, except at some locations
  62. * given by exceptionpos where it must use the values from
  63. * exceptionval. We write to "out".
  64. */
  65. __attribute__ ((noinline)) void patchedcopy(const uint * const  __restrict__ begin,
  66.         const uint * const  end,
  67.         const  uint * __restrict__ exceptionval,
  68.         const vector<uint> & exceptionpos,
  69.     uint * __restrict__ out) {
  70.     uint * __restrict__ tmpout = out;
  71.     for(const uint *  __restrict__ i = begin; i!=end;++i) {
  72.         *(tmpout++) = *i;
  73.     }
  74.     for(vector<uint>::const_iterator pos = exceptionpos.begin(); pos!= exceptionpos.end();++pos) {
  75.         *(out + *pos) = *(exceptionval++);
  76.     }
  77. }
  78.  
  79. /**
  80. * This copies the data from begin to end, except at some locations
  81. * given by exceptionpos where it must use the values from
  82. * exceptionval. We write to "out".
  83. *
  84. * Proposed by Luc Golden
  85. */
  86. __attribute__ ((noinline)) void patchedcopy2(const uint * const  __restrict__ begin,
  87.         const uint * const  end,
  88.         const  uint * __restrict__ exceptionval,
  89.         const vector<uint> & exceptionpos,
  90.     uint * __restrict__ out) {
  91.     vector<uint>::const_iterator pos = exceptionpos.begin();
  92.     const uint *  __restrict__ i = begin;
  93.     for(; i!=end;++i) {
  94.         if(i-begin == *pos) {
  95.             *(out++) =  *(exceptionval++);
  96.             ++pos;
  97.             if(pos==exceptionpos.end()) {
  98.               // no more exceptions
  99.               for(;i!=end;++i) {
  100.                 *(out++) = *i;
  101.               }
  102.               break;
  103.             }
  104.         } else
  105.             *(out++) = *i;
  106.     }
  107.    
  108. }
  109.  
  110.  
  111.  
  112. /**
  113. * This copies the data from begin to end, except at some locations
  114. * given by exceptionbitmap where it must use the values from
  115. * exceptionval. We write to "out".
  116. */
  117. __attribute__ ((noinline)) void bitmapcopy(const uint * const  __restrict__ begin,
  118.         const uint * const  end,
  119.         const  uint * __restrict__ exceptionval,
  120.         const vector<uint> & exceptionbitmap,
  121.     uint * __restrict__ out) {
  122.     vector<uint>::const_iterator j = exceptionbitmap.begin();
  123.     for(const uint *  __restrict__ i = begin; i<end;++i) {
  124.         for(uint k = 0; k<32;++k,++i)
  125.             *(out++) = ((*j) & (1U<<k))? *(exceptionval++) : *i;
  126.         ++j;
  127.     }
  128. }
  129.  
  130. /**
  131. * This copies the data from begin to end, except at some locations
  132. * given by exceptionbitmap where it must use the values from
  133. * exceptionval. We write to "out".
  134. */
  135. __attribute__ ((noinline)) void bitmapcopy8bits(const uint * const  __restrict__ begin,
  136.         const uint * const  end,
  137.         const  uint * __restrict__ exceptionval,
  138.         const vector<uint> & exceptionbitmap,
  139.     uint * __restrict__ out) {
  140.     const byte * __restrict__ j = reinterpret_cast<const byte *>(&exceptionbitmap[0]);
  141.     for(const uint *  __restrict__ i = begin; i<end;++i) {
  142.         for(uint k = 0; k<8;++k,++i)
  143.             *(out++) = ((*j) & (1U<<k))? *(exceptionval++) : *i;
  144.         ++j;
  145.     }
  146. }
  147.  
  148.  
  149.  
  150.  
  151. vector<uint> generateArray(uint N) {
  152.     vector<uint> ans(N);
  153.     for(uint k = 0; k<N;++k)
  154.       ans[k] = rand();
  155.     return ans;
  156. }
  157.  
  158. pair<vector<uint>, vector<uint> > generateExceptLocations(uint N, uint density) {
  159.     vector<uint> positions;
  160.     vector<uint> bitmap(N/32);
  161.     for(uint k = 0; k<N;k+= density) {
  162.         positions.push_back(k);
  163.         bitmap[k/32] &= (1<<(k%32));
  164.     }
  165.     return pair<vector<uint>, vector<uint> >(positions,bitmap);
  166. }
  167. int main() {
  168.     uint N = 1000000*32;//1024*1024*100;
  169.     uint density = 100;
  170.     vector<uint> data = generateArray(N);
  171.     vector<uint> out(N);
  172.     ZTimer z;
  173.  
  174.     vector<uint> exceptionvals = generateArray(N);// more than we need
  175.     cout <<" density(%)\t time with patching \t Luc Golden\t time with bitmaps\t time with 8-bit bitmaps\t justcopy"<<endl;
  176.     for(uint density = 1; density<50; density+=5) {
  177.         pair<vector<uint>, vector<uint> > exceptionpos = generateExceptLocations( N, density);
  178.    
  179.         cout<<100.0/density<<"\t\t\t";
  180.  
  181.        
  182.         z.reset();
  183.         patchedcopy(& data[0],
  184.         (& data[0]) + N,
  185.         &  exceptionvals[0],
  186.         exceptionpos.first,
  187.         &out[0]);
  188.         cout<<z.split()<<"\t\t\t";
  189.  
  190.         z.reset();
  191.         patchedcopy2(& data[0],
  192.         (& data[0]) + N,
  193.         &  exceptionvals[0],
  194.         exceptionpos.first,
  195.         &out[0]);
  196.         cout<<z.split()<<"\t\t\t";
  197.  
  198.         z.reset();
  199.         bitmapcopy(& data[0],
  200.         (& data[0]) + N,
  201.         &  exceptionvals[0],
  202.         exceptionpos.second,
  203.         &out[0]);  
  204.         cout<<z.split()<<"\t\t\t";
  205.  
  206.  
  207.         z.reset();
  208.         bitmapcopy8bits(& data[0],
  209.         (& data[0]) + N,
  210.         &  exceptionvals[0],
  211.         exceptionpos.second,
  212.         &out[0]);  
  213.         cout<<z.split()<<"\t\t\t";
  214.  
  215.  
  216.         z.reset();
  217.         justcopy(& data[0],
  218.         (& data[0]) + N,
  219.         &out[0]);  
  220.         cout<<z.split()<<"\t";
  221.  
  222.        
  223.         cout<<endl;
  224.     }
  225.     return 0;
  226. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement