Advertisement
zhangsongcui

TryDivide

Oct 15th, 2019
242
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 3.05 KB | None | 0 0
  1. // Requires .NET Core 3.0
  2.  
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Diagnostics;
  6. using System.Runtime.Intrinsics;
  7. using System.Runtime.Intrinsics.X86;
  8.  
  9. class Program {
  10.  
  11.     static int TryDivide(int size) {
  12.         var primes = new List<Vector256<float>>() {
  13.             Vector256.Create(16777216f, 16777216f, 16777216f, 16777216f, 16777216f, 16777216f, 3f, 2f)
  14.         };
  15.         int sqr = 2, maxSqr = (int)Math.Sqrt(size);
  16.         int pos = Vector256<float>.Count - 3;
  17.         bool flag = true;
  18.         int fastSize = Math.Min(size, 16777216);
  19.         int current = 5;
  20.         int count = 2;
  21.  
  22.         for (; current <= fastSize; current += (flag = !flag) ? 4 : 2) {
  23.             var num = Vector256.Create((float)current);
  24.             if (sqr * sqr <= current) {
  25.                 ++sqr;
  26.             }
  27.  
  28.             for (var i = 0; i < primes.Count; ++i) {
  29.                 var divisor = primes[i];
  30.                 var div = Avx.Divide(num, divisor);
  31.                 var temp = Avx.Compare(div, Avx.Floor(div), FloatComparisonMode.OrderedEqualNonSignaling);
  32.                 if (!Avx.TestZ(temp, temp)) {
  33.                     break; // not prime
  34.                 }
  35.                 if ((int)divisor.ToScalar() >= sqr) {
  36.                     // prime number found
  37.                     ++count;
  38.                     if (current <= maxSqr) {
  39.                         // we only stores values <= sqrt(size)
  40.                         primes[primes.Count - 1] = primes[primes.Count - 1].WithElement(pos, current);
  41.                         if (--pos < 0) {
  42.                             primes.Add(Vector256.Create(16777216f));
  43.                             pos = Vector256<float>.Count - 1;
  44.                         }
  45.                     }
  46.  
  47.                     break;
  48.                 }
  49.             }
  50.         }
  51.  
  52.         while (current <= size) {
  53.             var num = Vector256.Create((double)current);
  54.             if (sqr * sqr <= current) {
  55.                 ++sqr;
  56.             }
  57.  
  58.             for (var i = 0; i < primes.Count; ++i) {
  59.                 for (byte j = 1; j != byte.MaxValue; --j) {
  60.                     var divisor = Avx.ConvertToVector256Double(Avx.ExtractVector128(primes[i], j));
  61.                     var div = Avx.Divide(num, divisor);
  62.                     var temp = Avx.Compare(div, Avx.Floor(div), FloatComparisonMode.OrderedEqualNonSignaling);
  63.                     if (!Avx.TestZ(temp, temp)) {
  64.                         goto next; // not prime
  65.                     }
  66.                     if ((int)divisor.ToScalar() >= sqr) {
  67.                         // prime number found
  68.                         ++count;
  69.                         goto next;
  70.                     }
  71.                 }
  72.             }
  73.  
  74.         next:
  75.             current += (flag = !flag) ? 4 : 2;
  76.         }
  77.  
  78.         return count;
  79.     }
  80.  
  81.     static void Main() {
  82.         const int size = 10000_0000;
  83.         var watch = Stopwatch.StartNew();
  84.         Console.WriteLine("{0}: {1}", size, TryDivide(size));
  85.         watch.Stop();
  86.         Console.WriteLine(watch.Elapsed);
  87.     }
  88. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement