Advertisement
zhangsongcui

prime number count

Oct 13th, 2019
228
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 7.39 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.Linq;
  5. using System.Runtime.Intrinsics;
  6. using System.Runtime.Intrinsics.X86;
  7. using System.Threading.Tasks;
  8. using System.Numerics;
  9.  
  10. class Program {
  11.     static int Algo1(int size) {
  12.         const int core = 8;
  13.         const int MaxSafeInteger = 16_777_216;
  14.  
  15.         return (size > MaxSafeInteger ? 1_077_871 : 8) + Enumerable.Range(0, core).Select(i => Task.Run(() => {
  16.             int count = 0;
  17.             int known = size > MaxSafeInteger ? MaxSafeInteger + 1 : 21 ;
  18.             int coreSize = (size - known) / core;
  19.             int start = known + coreSize * i;
  20.             if (start % 2 == 0) ++start;
  21.             int end = i == core - 1 ? size : start + coreSize;
  22.  
  23.             int sqr = (int)Math.Sqrt(start);
  24.  
  25.             if (size <= MaxSafeInteger) {
  26.                 for (int current = start; current <= end; current += 2) {
  27.                     if (sqr * sqr <= current) {
  28.                         ++sqr;
  29.                     }
  30.                     var num = Vector256.Create((float)current);
  31.  
  32.                     for (var divisor = Vector256.Create(17f, 15f, 13f, 11f, 9f, 7f, 5f, 3f); ; divisor = Avx.Add(divisor, Vector256.Create(16f))) {
  33.                         var div = Avx.Divide(num, divisor);
  34.                         var temp = Avx.Compare(div, Avx.Floor(div), FloatComparisonMode.OrderedEqualNonSignaling);
  35.  
  36.                         if (!Avx.TestZ(temp, temp)) {
  37.                             break; // not prime
  38.                         }
  39.                         if ((int)divisor.ToScalar() >= sqr) {
  40.                             ++count;
  41.                             break;
  42.                         }
  43.                     }
  44.                 }
  45.             } else {
  46.                 for (int current = start; current < end; current += 2) {
  47.                     if (sqr * sqr <= current) {
  48.                         ++sqr;
  49.                     }
  50.  
  51.                     var num = Vector256.Create((double)current);
  52.  
  53.                     for (var divisor = Vector256.Create(9d, 7d, 5d, 3d); ; divisor = Avx.Add(divisor, Vector256.Create(8d))) {
  54.                         var div = Avx.Divide(num, divisor);
  55.                         var temp = Avx.Compare(div, Avx.Floor(div), FloatComparisonMode.OrderedEqualNonSignaling);
  56.  
  57.                         if (!Avx.TestZ(temp, temp)) {
  58.                             break; // not prime
  59.                         }
  60.                         if ((int)divisor.ToScalar() >= sqr) {
  61.                             ++count;
  62.                             break;
  63.                         }
  64.                     }
  65.                 }
  66.             }
  67.  
  68.             return count;
  69.         })).ToArray().Select(task => task.Result).Sum();
  70.     }
  71.  
  72.     static int Old(int size) {
  73.         int sqr = 4;
  74.         int count = 8;
  75.  
  76.         for (int current = 21; current < size; current += 2) {
  77.             if (sqr * sqr <= current) {
  78.                 ++sqr;
  79.             }
  80.  
  81.             var num = Vector256.Create((double)current);
  82.  
  83.             for (var divisor = Vector256.Create(9d, 7d, 5d, 3d); ; divisor = Avx.Add(divisor, Vector256.Create(8d))) {
  84.                 var div = Avx.Divide(num, divisor);
  85.                 var temp = Avx.Compare(div, Avx.Floor(div), FloatComparisonMode.OrderedEqualNonSignaling);
  86.  
  87.                 if (!Avx.TestZ(temp, temp)) {
  88.                     break; // not prime
  89.                 }
  90.                 if ((int)divisor.ToScalar() >= sqr) {
  91.                     ++count;
  92.                     break;
  93.                 }
  94.             }
  95.         }
  96.  
  97.         return count;
  98.     }
  99.  
  100.     static int TryDivide(int size) {
  101.         var primes = new List<Vector256<float>>(134734) {
  102.             Vector256.Create(16777216f, 16777216f, 16777216f, 16777216f, 16777216f, 16777216f, 3f, 2f)
  103.         };
  104.         int sqr = 2, maxSqr = (int)Math.Sqrt(size);
  105.         int pos = Vector256<float>.Count - 3;
  106.         bool flag = true;
  107.         int fastSize = Math.Min(size, 16777216);
  108.         int current = 5;
  109.         int count = 2;
  110.  
  111.         for (; current <= fastSize; current += (flag = !flag) ? 4 : 2) {
  112.             var num = Vector256.Create((float)current);
  113.             if (sqr * sqr <= current) {
  114.                 ++sqr;
  115.             }
  116.  
  117.             for (var i = 0; i < primes.Count; ++i) {
  118.                 var divisor = primes[i];
  119.                 var div = Avx.Divide(num, divisor);
  120.                 var temp = Avx.Compare(div, Avx.Floor(div), FloatComparisonMode.OrderedEqualNonSignaling);
  121.                 if (!Avx.TestZ(temp, temp)) {
  122.                     break; // not prime
  123.                 }
  124.                 if ((int)divisor.ToScalar() >= sqr) {
  125.                     // prime number found
  126.                     ++count;
  127.                     if (current <= maxSqr) {
  128.                         // we only stores values <= sqrt(size)
  129.                         primes[primes.Count - 1] = primes[primes.Count - 1].WithElement(pos, current);
  130.                         if (--pos < 0) {
  131.                             primes.Add(Vector256.Create(16777216f));
  132.                             pos = Vector256<float>.Count - 1;
  133.                         }
  134.                     }
  135.  
  136.                     break;
  137.                 }
  138.             }
  139.         }
  140.  
  141.         if (current <= size) {
  142.             do {
  143.                 var num = Vector256.Create((double)current);
  144.                 if (sqr * sqr <= current) {
  145.                     ++sqr;
  146.                 }
  147.  
  148.                 for (var i = 0; i < primes.Count; ++i) {
  149.                     for (byte j = 1; j != byte.MaxValue; --j) {
  150.                         var divisor = Avx.ConvertToVector256Double(Avx.ExtractVector128(primes[i], j));
  151.                         var div = Avx.Divide(num, divisor);
  152.                         var temp = Avx.Compare(div, Avx.Floor(div), FloatComparisonMode.OrderedEqualNonSignaling);
  153.                         if (!Avx.TestZ(temp, temp)) {
  154.                             goto next; // not prime
  155.                         }
  156.                         if ((int)divisor.ToScalar() >= sqr) {
  157.                             // prime number found
  158.                             ++count;
  159.                             goto next;
  160.                         }
  161.                     }
  162.                 }
  163.  
  164.             next:
  165.                 current += (flag = !flag) ? 4 : 2;
  166.             } while (current <= size);
  167.         }
  168.  
  169.         return count;
  170.     }
  171.  
  172.     static int Select(int size) {
  173.         var span = new Span<ulong>(new ulong[size / 32 + 1]);
  174.         span.Fill(ulong.MaxValue);
  175.         BitOps.ClearBit(ref span[0], 0);
  176.  
  177.         for (var i = 0; i < size / 32; ++i) {
  178.             for (var j = 0; j < 32; ++j) {
  179.                
  180.                 var lz = BitOperations.TrailingZeroCount(span[i] & (~0Lu >> j));
  181.                 Console.WriteLine(lz);
  182.  
  183.                 int k = lz, n;
  184.                 n = BitOperations.TrailingZeroCount(span[i] & (~0Lu >> k << k));
  185.                 BitOps.ClearBit(ref span[i], (lz + 1) * (n + 1) - 1);
  186.                 ++k;
  187.  
  188.                 n = BitOperations.TrailingZeroCount(span[i] & (~0Lu >> k << k));
  189.                 BitOps.ClearBit(ref span[i], (lz + 1) * (n + 1) - 1);
  190.             }
  191.         }
  192.         return size;
  193.     }
  194.  
  195.     static void Main() {
  196.         const int size = 32;
  197.         var watch = Stopwatch.StartNew();
  198.         Console.WriteLine("{0}: {1}", size, Select(size));
  199.         watch.Stop();
  200.         Console.WriteLine(watch.Elapsed);
  201.     }
  202. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement