Guest User

Untitled

a guest
Aug 11th, 2013
208
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.89 KB | None | 0 0
  1. #include <iostream>
  2. #include <array>
  3. #include <amp.h>
  4. #include <stdio.h>
  5. #include <tchar.h>
  6. #include <immintrin.h>
  7. using namespace concurrency;
  8. using namespace std;
  9.  
  10. union ieee754_QNAN
  11. {
  12.     const float f;
  13.     struct
  14.     {
  15.         const unsigned int mantissa:23, exp:8, sign:1;
  16.     };
  17.  
  18.     ieee754_QNAN() : f(0.0), mantissa(0x7FFFFF), exp(0xFF), sign(0x0) {}
  19. };
  20.  
  21. _MM_ALIGN16 const ieee754_QNAN absMask;
  22. static const __m256 abs4Mask = _mm256_set1_ps(absMask.f);
  23.  
  24. const __m256 _mm256_abs_ps(const __m256& x)
  25. {
  26.     return _mm256_and_ps(abs4Mask, x);
  27. }
  28.  
  29. int _tmain(int argc, _TCHAR* argv[])
  30. {
  31.     LARGE_INTEGER timeStart;
  32.     QueryPerformanceCounter(&timeStart);
  33.    
  34.     const int wantedNumPrimes = 10000;
  35.     const int step = 10000;
  36.  
  37.     std::vector<int> primes;
  38.     std::vector<float> primesInv;
  39.     primes.reserve(wantedNumPrimes * 2);
  40.     primesInv.reserve(wantedNumPrimes * 2);
  41.  
  42.     primes.push_back(2);
  43.     primesInv.push_back(1.0f / 2.0f);
  44.  
  45.     primes.push_back(3);
  46.     primesInv.push_back(1.0f / 3.0f);
  47.  
  48.     primes.push_back(5);
  49.     primesInv.push_back(1.0f / 5.0f);
  50.  
  51.     primes.push_back(7);
  52.     primesInv.push_back(1.0f / 7.0f);
  53.  
  54.     primes.push_back(11);
  55.     primesInv.push_back(1.0f / 11.0f);
  56.  
  57.     primes.push_back(13);
  58.     primesInv.push_back(1.0f / 13.0f);
  59.  
  60.     primes.push_back(17);
  61.     primesInv.push_back(1.0f / 17.0f);
  62.  
  63.     primes.push_back(19);
  64.     primesInv.push_back(1.0f / 19.0f);
  65.  
  66.     int blockStart = 20;
  67.     while(primes.size() < wantedNumPrimes)
  68.     {
  69.         int from = blockStart;
  70.         int to = blockStart + step;
  71.         blockStart = to;
  72.  
  73.         for(int n = from; n < to; n += 8)
  74.         {
  75.             __m256 n8 = _mm256_set_ps(n, n + 1, n + 2, n + 3, n + 4, n + 5, n + 6, n + 7);
  76.  
  77.             __m256 isPrimeMask8 = _mm256_setzero_ps();
  78.             int isPrimeMask = 0;
  79.             int wall = n + 7;
  80.             for(int i = 0; i < primes.size(); i++)
  81.             {
  82.                 if(primes[i] * primes[i] >= wall)
  83.                     break;
  84.  
  85.                 __m256 rcp = _mm256_set1_ps(primesInv[i]);
  86.  
  87.                 __m256 divisionRes = _mm256_mul_ps(n8, rcp);
  88.                 __m256i rounded = _mm256_cvtps_epi32(divisionRes);
  89.  
  90.                 __m256 rounded8 = _mm256_cvtepi32_ps(rounded);
  91.                 __m256 diff = _mm256_abs_ps(_mm256_sub_ps(rounded8, divisionRes));
  92.                 __m256 cmpResult = _mm256_cmp_ps(diff, _mm256_set1_ps(0.001f), _CMP_LT_OS);
  93.                 isPrimeMask8 = _mm256_or_ps(isPrimeMask8, cmpResult);
  94.  
  95.                 isPrimeMask = _mm256_movemask_ps(isPrimeMask8);
  96.  
  97.                 if(isPrimeMask == 255)
  98.                     break;
  99.             }
  100.  
  101.             if(isPrimeMask == 255)
  102.                 continue;
  103.  
  104.             if((isPrimeMask & 0x80) == 0)
  105.             {
  106.                 int prime = n;
  107.                 primes.push_back(prime);
  108.                 primesInv.push_back(1.0f / prime);
  109.             }
  110.  
  111.             if((isPrimeMask & 0x40) == 0)
  112.             {
  113.                 int prime = n + 1;
  114.                 primes.push_back(prime);
  115.                 primesInv.push_back(1.0f / prime);
  116.             }
  117.  
  118.             if((isPrimeMask & 0x20) == 0)
  119.             {
  120.                 int prime = n + 2;
  121.                 primes.push_back(prime);
  122.                 primesInv.push_back(1.0f / prime);
  123.             }
  124.  
  125.             if((isPrimeMask & 0x10) == 0)
  126.             {
  127.                 int prime = n + 3;
  128.                 primes.push_back(prime);
  129.                 primesInv.push_back(1.0f / prime);
  130.             }
  131.  
  132.             if((isPrimeMask & 0x8) == 0)
  133.             {
  134.                 int prime = n + 4;
  135.                 primes.push_back(prime);
  136.                 primesInv.push_back(1.0f / prime);
  137.             }
  138.  
  139.             if((isPrimeMask & 0x4) == 0)
  140.             {
  141.                 int prime = n + 5;
  142.                 primes.push_back(prime);
  143.                 primesInv.push_back(1.0f / prime);
  144.             }
  145.  
  146.             if((isPrimeMask & 0x2) == 0)
  147.             {
  148.                 int prime = n + 6;
  149.                 primes.push_back(prime);
  150.                 primesInv.push_back(1.0f / prime);
  151.             }
  152.  
  153.             if((isPrimeMask & 0x1) == 0)
  154.             {
  155.                 int prime = n + 7;
  156.                 primes.push_back(prime);
  157.                 primesInv.push_back(1.0f / prime);
  158.             }
  159.         }
  160.     }
  161.  
  162.     LARGE_INTEGER timeEnd;
  163.     QueryPerformanceCounter(&timeEnd);
  164.     float timeDiff = timeEnd.LowPart - timeStart.LowPart;
  165.  
  166.     LARGE_INTEGER freqPerSecond;
  167.     QueryPerformanceFrequency(&freqPerSecond);
  168.     float time = (timeDiff * 1000.0f)/(float)freqPerSecond.LowPart;
  169.  
  170.     for(int i = 0; i < 10000; i++)
  171.     {
  172.         cout << primes[i] << " ";
  173.     }
  174.  
  175.     cout<<"Time elapsed: "<<time<<"ms";
  176.  
  177.     int a;
  178.     cin>>a;
  179.  
  180.     return 0;
  181. }
Advertisement
Add Comment
Please, Sign In to add comment