Advertisement
Guest User

Untitled

a guest
May 14th, 2018
120
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.87 KB | None | 0 0
  1. #include "stdafx.h"
  2. #include <algorithm>
  3. #include <vector>
  4. #include <stdint.h>
  5. #include <chrono>
  6. #include <thread>
  7.  
  8. #include <stdio.h>
  9.  
  10. using namespace std::chrono;
  11.  
  12. /// XorShift32 generator; extremely fast, 2^32-1 period, way better quality
  13. /// than LCG but fail some test suites
  14. struct XorShift32 {
  15.     /// This stuff allows to use this class wherever a library function
  16.     /// requires a UniformRandomBitGenerator (e.g. std::shuffle)
  17.     typedef uint32_t result_type;
  18.     static uint32_t min() { return 1; }
  19.     static uint32_t max() { return uint32_t(-1); }
  20.  
  21.     /// PRNG state
  22.     uint32_t y;
  23.  
  24.     /// Initializes with seed
  25.     XorShift32(uint32_t seed = 0) : y(seed) {
  26.         if (y == 0) y = 2463534242UL;
  27.     }
  28.  
  29.     /// Returns a value in the range [1, 1<<32)
  30.     uint32_t operator()() {
  31.         y ^= (y << 13);
  32.         y ^= (y >> 17);
  33.         y ^= (y << 15);
  34.         return y;
  35.     }
  36.  
  37.     /// Returns a value in the range [0, limit); this conforms to the RandomFunc
  38.     /// requirements for std::random_shuffle
  39.     uint32_t operator()(uint32_t limit) {
  40.         return (*this)() % limit;
  41.     }
  42. };
  43.  
  44.  
  45.  
  46. uint8_t lookup(std::vector<uint8_t>& main_arr, std::vector<uint32_t>& sec_arr, unsigned idx) {
  47.     // extract the 2 bits of our interest from the main array
  48.     uint8_t v = (main_arr[idx >> 2] >> (2 * (idx & 3))) & 3;
  49.     // usual (likely) case: value between 0 and 2
  50.     if (v != 3) return v;
  51.     // bad case: lookup the index<<8 in the secondary array
  52.     // lower_bound finds the first >=, so we don't need to mask out the value
  53.     auto ptr = std::lower_bound(sec_arr.begin(), sec_arr.end(), idx << 8);
  54. #ifdef _DEBUG
  55.     // some coherency checks
  56.     if (ptr == sec_arr.end()) std::abort();
  57.     if ((*ptr >> 8) != idx) std::abort();
  58. #endif
  59.     // extract our 8-bit value from the 32 bit (index, value) thingie
  60.     return (*ptr) & 0xff;
  61. }
  62.  
  63. void populate(std::vector<uint8_t>& main_arr, std::vector<uint32_t>& sec_arr, uint8_t *source, size_t size) {
  64.     main_arr.clear(); sec_arr.clear();
  65.     // size the main storage (round up)
  66.     main_arr.resize((size + 3) / 4);
  67.     for (size_t idx = 0; idx < size; ++idx) {
  68.         uint8_t in = source[idx];
  69.         uint8_t &target = main_arr[idx >> 2];
  70.         // if the input doesn't fit, cap to 3 and put in secondary storage
  71.         if (in >= 3) {
  72.             // top 24 bits: index; low 8 bit: value
  73.             sec_arr.push_back((idx << 8) | in);
  74.             in = 3;
  75.         }
  76.         // store in the target according to the position
  77.         target |= in << ((idx & 3) * 2);
  78.     }
  79. }
  80.  
  81. volatile unsigned out;
  82.  
  83. int all = 0;
  84. int all_count = 0;
  85.  
  86. int RunThreadTest() {
  87.  
  88.     std::vector<uint8_t> main_arr;
  89.     std::vector<uint32_t> sec_arr;
  90.  
  91.     XorShift32 xs;
  92.     std::vector<uint8_t> vec;
  93.     int size = 10000000;
  94.     for (int i = 0; i < size; ++i) {
  95.         uint32_t v = xs();
  96.         if (v < 1825361101)      v = 0; // 42.5%
  97.         else if (v < 4080218931) v = 1; // 95.0%
  98.         else if (v < 4252017623) v = 2; // 99.0%
  99.         else {
  100.             while ((v & 0xff) < 3) v = xs();
  101.         }
  102.         vec.push_back(v);
  103.     }
  104.     populate(main_arr, sec_arr, vec.data(), vec.size());
  105.  
  106.     std::this_thread::sleep_for(2s);
  107.  
  108.     printf("Start Benchmark\n");
  109.  
  110.    
  111.     for (int i = 0; i < 10; ++i) {
  112.         unsigned o = 0;
  113.         auto beg = high_resolution_clock::now();
  114.         for (int i = 0; i < size; ++i) {
  115.             o += lookup(main_arr, sec_arr, xs() % size);
  116.         }
  117.         out += o;
  118.         printf("lookup: %10d µs\n", int((high_resolution_clock::now() - beg) / microseconds(1)));
  119.         //o = 0;
  120.         //beg = high_resolution_clock::now();
  121.         //for (int i = 0; i < size; ++i) {
  122.         //  o += vec[xs() % size];
  123.         //}
  124.         //out += o;
  125.         //printf("array:  %10d µs\n", int((high_resolution_clock::now() - beg) / microseconds(1)));
  126.  
  127.         all += int((high_resolution_clock::now() - beg) / microseconds(1));
  128.         all_count++;
  129.     }
  130.  
  131.     printf("array all:  %10d µs\n", all / all_count);
  132.  
  133. }
  134.  
  135. int main() {
  136.    
  137.     const int numThreads = 6;
  138.  
  139.     std::thread tt[numThreads];
  140.  
  141.     for (int t = 0; t < numThreads; t++) {
  142.  
  143.         tt[t] = std::thread(RunThreadTest);
  144.  
  145.     }
  146.  
  147.     for (int t = 0; t < numThreads; t++) {
  148.  
  149.         tt[t].join();
  150.  
  151.     }
  152.  
  153.     return 0;
  154. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement