Advertisement
Guest User

Untitled

a guest
May 14th, 2018
140
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.07 KB | None | 0 0
  1. // ArrayTestProject.cpp : Defines the entry point for the console application.
  2. //
  3.  
  4. #include "stdafx.h"
  5.  
  6. #include <vector>
  7. #include <algorithm>
  8. #include <iostream>
  9. #include <chrono>
  10. #include "ArrayTestProject.h"
  11.  
  12. std::vector<uint8_t> main_arr_reg;
  13.  
  14. std::vector<uint8_t> main_arr;
  15. std::vector<uint32_t> sec_arr;
  16.  
  17. std::vector<int> rand_access_order;
  18.  
  19. static constexpr int NUMBER = 10000000;
  20.  
  21. int main()
  22. {
  23.     rand_access_order.resize(NUMBER);
  24.  
  25.     main_arr.resize(NUMBER/4);
  26.     main_arr_reg.resize(NUMBER);
  27.  
  28.     for (int i = 0; i < NUMBER; i++) {
  29.  
  30.         rand_access_order[i] = ((double)rand() / (double)RAND_MAX) * (NUMBER-1);
  31.  
  32.         float val = ((float) rand() / (float) RAND_MAX);
  33.  
  34.         int mainIndex = i >> 2;
  35.        
  36.         if (val < 0.5f) {
  37.             main_arr_reg[i] = 0;
  38.             main_arr[mainIndex] |= 0 << ((i & 3) * 2);
  39.         }
  40.         else if (val < 0.95f) {
  41.             main_arr_reg[i] = 1;
  42.             main_arr[mainIndex] |= 1 << ((i & 3) * 2);
  43.         }
  44.         else if (val < 0.99f) {
  45.             main_arr_reg[i] = 2;
  46.             main_arr[mainIndex] |= 2 << ((i & 3) * 2);
  47.         }
  48.         else {         
  49.             main_arr[mainIndex] |= 3 << ((i & 3) * 2);
  50.  
  51.             uint8_t randNew = ((float)rand() / (float)RAND_MAX) * 200 + 4;
  52.  
  53.             sec_arr.push_back((i << 8) | randNew);
  54.  
  55.             main_arr_reg[i] = randNew;
  56.  
  57.         }
  58.          
  59.     }
  60.  
  61.     {
  62.         std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
  63.  
  64.         DoTest0();
  65.  
  66.         std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
  67.  
  68.         std::cout << "0 Time difference = " << std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count() << std::endl;
  69.     }
  70.  
  71.     {
  72.         std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
  73.  
  74.         DoTest1();
  75.  
  76.         std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
  77.  
  78.         std::cout << "1 Time difference = " << std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count() << std::endl;
  79.     }
  80.    
  81.  
  82.     return 0;
  83. }
  84.  
  85. void DoTest0() {
  86.  
  87.     uint64_t sum = 0;
  88.  
  89.     for (int i = 0; i < NUMBER; ++i) {
  90.  
  91.         int randnum = ((double)rand() / (double)RAND_MAX) * (NUMBER - 1);
  92.  
  93.         sum += main_arr_reg[randnum];
  94.  
  95.     }
  96.  
  97.     std::cout << "0 Sum: " << sum << std::endl;
  98. }
  99.  
  100. void DoTest1() {
  101.  
  102.     uint64_t sum = 0;
  103.  
  104.     for (int i = 0; i < NUMBER; ++i) {
  105.  
  106.         int randnum = ((double)rand() / (double)RAND_MAX) * (NUMBER - 1);
  107.  
  108.         sum += lookup(randnum);
  109.  
  110.     }
  111.  
  112.     std::cout << "1 Sum: " << sum << std::endl;
  113. }
  114.  
  115.  
  116.  
  117. uint8_t lookup(unsigned idx) {
  118.     // extract the 2 bits of our interest from the main array
  119.     uint8_t v = (main_arr[idx >> 2] >> (2 * (idx & 3))) & 3;
  120.     // usual (likely) case: value between 0 and 2
  121.     if (v != 3) return v;
  122.     // bad case: lookup the index<<8 in the secondary array
  123.     // lower_bound finds the first >=, so we don't need to mask out the value
  124.     auto ptr = std::lower_bound(sec_arr.begin(), sec_arr.end(), idx << 8);
  125. #ifdef _DEBUG
  126.     // some coherency checks
  127.     if (ptr == sec_arr.end()) {
  128.         std::cout << "ERROR: " << uint8_t(idx << 8) << std::endl;
  129.         std::abort();
  130.     }
  131.     if ((*ptr >> 8) != idx) std::abort();
  132. #endif
  133.     // extract our 8-bit value from the 32 bit (index, value) thingie
  134.     return (*ptr) & 0xff;
  135. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement