Advertisement
P_P

SoE

P_P
Mar 13th, 2018
196
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.75 KB | None | 0 0
  1. //    https://codereview.stackexchange.com/q/189083
  2.  
  3. //    https://pastebin.com/JMdTxbeJ
  4. //    Segmented SoE (primes < 2^32 in 4.6 seconds).
  5.  
  6. /*                    old-ns-new               old-s-new
  7.       primes <   25     47    47    p < 2^31   7.4   7.0
  8.              <   50     62    63      < 2^32  15.8  15.0
  9.              <  100    109    78
  10.              <  200    187   141
  11.              <  400    312   218
  12.              <  800    578   375
  13.              < 1600   1092   718
  14.              < 3200   2152  1435
  15.              < 6400   4274  2855                           */
  16.  
  17. #include "stdafx.h"
  18. #include <vector>
  19. #include <iostream>
  20. #include <ctime>
  21. #include <Windows.h>
  22. using namespace std;
  23. typedef unsigned int u32;
  24. vector<u32> x; vector<u32> p;
  25.  
  26. void buildX(u32 m)  // mark odd composites
  27. {
  28.     m -= m / ~0u; m += m & 1; m >>= 1;
  29.     u32 a = 1, b = 2, c = 3, d = m >> 5;
  30.     x.resize(d + 1); x[0] = 0x9b4b3491;
  31.     for (; a <= d; a += 3) x[a] = 0x24924924;
  32.     for (; b <= d; b += 3) x[b] = 0x49249249;
  33.     for (; c <= d; c += 3) x[c] = 0x92492492;
  34.     for (a = 1; a <= d; a += 5) x[a] |= 0x42108421;
  35.     for (a = 2; a <= d; a += 5) x[a] |= 0x10842108;
  36.     for (a = 3; a <= d; a += 5) x[a] |= 0x84210842;
  37.     for (a = 4; a <= d; a += 5) x[a] |= 0x21084210;
  38.     for (a = 5; a <= d; a += 5) x[a] |= 0x08421084;
  39.     for (a = 7, b = 24, c = 12; b < m; a += 2, b += c += 4)
  40.         if ((x[a >> 6] & 1 << (a >> 1)) == 0)
  41.             for (d = b; d < m; d += a) x[d >> 5] |= 1 << d;
  42.     x[m >> 5] |= ~0u << m;
  43. }
  44.  
  45. void countPrimes()
  46. {
  47.     u32 c = 1; int i = x.size() - 1;
  48.     while (i >= 0) c += __popcnt(~x[i--]);
  49.     p.resize(c);
  50. }
  51.  
  52. void primes(u32 m)  // primes <= m
  53. {
  54.     if (m > 1)
  55.     {
  56.         buildX(m); countPrimes(); p[0] = 2;
  57.         u32 u = 1, v = 1, xi; DWORD tz;
  58.         for (int i = 0, n = 1, c = p.size(); n < c; v = u += 64)
  59.             for (xi = ~x[i++]; xi;)
  60.             {
  61.                 _BitScanForward(&tz, xi); xi >>= tz; xi >>= 1;
  62.                 p[n++] = v += tz << 1; v += 2;
  63.             }
  64.     }
  65. }
  66.  
  67. int main()
  68. {
  69.     for (u32 m = 25; m <= 6400; m <<= 1)  // for (u32 m = 0; m < 9; m++)
  70.     {
  71.         primes(m);
  72.         if (m > 1)
  73.         {
  74.             u32 maxP = p[p.size() - 1];
  75.             cout << "largest prime <= " << m << " : " << maxP << "  ";
  76.         }
  77.         clock_t clock0 = clock();
  78.         for (int i = 1000000; i; i--)
  79.         {
  80.             x.resize(0); p.resize(0); primes(m);
  81.         }
  82.         cout << clock() - clock0 << " ns: ";
  83.         cout << p.size() << " primes" << endl << endl;
  84.     }
  85.     x.resize(0); p.resize(0); u32 m = ~0u >> 1;
  86.     clock_t clock0 = clock(); primes(m);
  87.     cout << clock() - clock0 << " ms: ";
  88.     cout << p.size() << " primes <= " << m << endl;
  89.     getchar();
  90. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement