Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Requires .NET Core 3.0
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Runtime.Intrinsics;
- using System.Runtime.Intrinsics.X86;
- class Program {
- static int TryDivide(int size) {
- var primes = new List<Vector256<float>>() {
- Vector256.Create(16777216f, 16777216f, 16777216f, 16777216f, 16777216f, 16777216f, 3f, 2f)
- };
- int sqr = 2, maxSqr = (int)Math.Sqrt(size);
- int pos = Vector256<float>.Count - 3;
- bool flag = true;
- int fastSize = Math.Min(size, 16777216);
- int current = 5;
- int count = 2;
- for (; current <= fastSize; current += (flag = !flag) ? 4 : 2) {
- var num = Vector256.Create((float)current);
- if (sqr * sqr <= current) {
- ++sqr;
- }
- for (var i = 0; i < primes.Count; ++i) {
- var divisor = primes[i];
- var div = Avx.Divide(num, divisor);
- var temp = Avx.Compare(div, Avx.Floor(div), FloatComparisonMode.OrderedEqualNonSignaling);
- if (!Avx.TestZ(temp, temp)) {
- break; // not prime
- }
- if ((int)divisor.ToScalar() >= sqr) {
- // prime number found
- ++count;
- if (current <= maxSqr) {
- // we only stores values <= sqrt(size)
- primes[primes.Count - 1] = primes[primes.Count - 1].WithElement(pos, current);
- if (--pos < 0) {
- primes.Add(Vector256.Create(16777216f));
- pos = Vector256<float>.Count - 1;
- }
- }
- break;
- }
- }
- }
- while (current <= size) {
- var num = Vector256.Create((double)current);
- if (sqr * sqr <= current) {
- ++sqr;
- }
- for (var i = 0; i < primes.Count; ++i) {
- for (byte j = 1; j != byte.MaxValue; --j) {
- var divisor = Avx.ConvertToVector256Double(Avx.ExtractVector128(primes[i], j));
- var div = Avx.Divide(num, divisor);
- var temp = Avx.Compare(div, Avx.Floor(div), FloatComparisonMode.OrderedEqualNonSignaling);
- if (!Avx.TestZ(temp, temp)) {
- goto next; // not prime
- }
- if ((int)divisor.ToScalar() >= sqr) {
- // prime number found
- ++count;
- goto next;
- }
- }
- }
- next:
- current += (flag = !flag) ? 4 : 2;
- }
- return count;
- }
- static void Main() {
- const int size = 10000_0000;
- var watch = Stopwatch.StartNew();
- Console.WriteLine("{0}: {1}", size, TryDivide(size));
- watch.Stop();
- Console.WriteLine(watch.Elapsed);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement