Revert "Iterate candidate exponents via prime merge walk"
This reverts commit 3223a2fbc0.
This commit is contained in:
1 parent
2466661b73
commit
be3b7aedec
2 files changed
+23
-99
No files matched your search
@@ -12,8 +12,4 @@
|
|||||||
<_Parameter1>EvenPerfectBitScanner.Tests</_Parameter1>
|
<_Parameter1>EvenPerfectBitScanner.Tests</_Parameter1>
|
||||||
</AssemblyAttribute>
|
</AssemblyAttribute>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Open.Numeric" Version="3.0.1" />
|
|
||||||
<PackageReference Include="Open.Numeric.Primes" Version="4.0.4" />
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
</Project>
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Open.Numeric.Primes;
|
|
||||||
using PerfectNumbers.Core;
|
using PerfectNumbers.Core;
|
||||||
using PerfectNumbers.Core.Gpu;
|
using PerfectNumbers.Core.Gpu;
|
||||||
|
|
||||||
@@ -31,13 +30,7 @@ internal static class Program
|
|||||||
private static MersenneNumberDivisorGpuTester? _divisorTester;
|
private static MersenneNumberDivisorGpuTester? _divisorTester;
|
||||||
private static ulong? _orderWarmupLimitOverride;
|
private static ulong? _orderWarmupLimitOverride;
|
||||||
private static unsafe delegate*<ulong, ref ulong, ulong> _transformP;
|
private static unsafe delegate*<ulong, ref ulong, ulong> _transformP;
|
||||||
private static readonly object PrimeMergeSync = new();
|
private static long _state;
|
||||||
private static readonly TrialDivision.U64.Memoized PrimeGenerator = new();
|
|
||||||
private static IEnumerator<ulong>? _primeEnumerator;
|
|
||||||
private static bool _hasNextPrime;
|
|
||||||
private static ulong _nextPrime;
|
|
||||||
private static ulong _currentCandidate;
|
|
||||||
private static ulong _currentRemainder;
|
|
||||||
private static bool _limitReached;
|
private static bool _limitReached;
|
||||||
private static string? _resultsDir;
|
private static string? _resultsDir;
|
||||||
private static string? _resultsPrefix;
|
private static string? _resultsPrefix;
|
||||||
@@ -576,7 +569,7 @@ internal static class Program
|
|||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine("Starting scan...");
|
Console.WriteLine("Starting scan...");
|
||||||
InitializePrimeMerge(currentP, remainder);
|
_state = ((long)currentP << 3) | (long)remainder;
|
||||||
Task[] tasks = new Task[threadCount];
|
Task[] tasks = new Task[threadCount];
|
||||||
|
|
||||||
for (int i = 0; i < threadCount; i++)
|
for (int i = 0; i < threadCount; i++)
|
||||||
@@ -743,104 +736,39 @@ internal static class Program
|
|||||||
return $"even_perfect_bit_scan_inc-{inc}_thr-{threads}_blk-{block}_mers-{mers}_mersdev-{mersenneDevice}_ntt-{ntt}_red-{red}_primesdev-{primesDevice}_{order}_orderdev-{orderDevice}_{gcd}_{work}_gputh-{gpuPrimeThreads}_llslice-{llSlice}_scanb-{gpuScanBatch}_warm-{warmupLimit}.csv";
|
return $"even_perfect_bit_scan_inc-{inc}_thr-{threads}_blk-{block}_mers-{mers}_mersdev-{mersenneDevice}_ntt-{ntt}_red-{red}_primesdev-{primesDevice}_{order}_orderdev-{orderDevice}_{gcd}_{work}_gputh-{gpuPrimeThreads}_llslice-{llSlice}_scanb-{gpuScanBatch}_warm-{warmupLimit}.csv";
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
private static void InitializePrimeMerge(ulong startCandidate, ulong startRemainder)
|
|
||||||
{
|
|
||||||
lock (PrimeMergeSync)
|
|
||||||
{
|
|
||||||
_currentCandidate = startCandidate;
|
|
||||||
_currentRemainder = startRemainder;
|
|
||||||
InitializePrimeEnumerator(startCandidate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
private static void InitializePrimeEnumerator(ulong startValue)
|
|
||||||
{
|
|
||||||
(_primeEnumerator as IDisposable)?.Dispose();
|
|
||||||
ulong begin = startValue;
|
|
||||||
_primeEnumerator = PrimeGenerator.StartingAt(in begin).GetEnumerator();
|
|
||||||
_hasNextPrime = MoveToNextPrime();
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
private static bool MoveToNextPrime()
|
|
||||||
{
|
|
||||||
if (_primeEnumerator is null)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_primeEnumerator.MoveNext())
|
|
||||||
{
|
|
||||||
_nextPrime = _primeEnumerator.Current;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Volatile.Write(ref _limitReached, true);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
private static bool EnsurePrimeForCandidate(ulong candidate)
|
|
||||||
{
|
|
||||||
if (!_hasNextPrime)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (_hasNextPrime && _nextPrime < candidate)
|
|
||||||
{
|
|
||||||
_hasNextPrime = MoveToNextPrime();
|
|
||||||
}
|
|
||||||
|
|
||||||
return _hasNextPrime;
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private static unsafe int ReserveBlock(ulong[] buffer, int blockSize)
|
private static unsafe int ReserveBlock(ulong[] buffer, int blockSize)
|
||||||
{
|
{
|
||||||
Span<ulong> bufferSpan = new(buffer);
|
Span<ulong> bufferSpan = new(buffer);
|
||||||
int count = 0;
|
ulong p, remainder;
|
||||||
|
long state, newState, original;
|
||||||
lock (PrimeMergeSync)
|
int count;
|
||||||
|
while (true)
|
||||||
{
|
{
|
||||||
if (!_hasNextPrime && !MoveToNextPrime())
|
state = Volatile.Read(ref _state);
|
||||||
|
p = (ulong)state >> 3;
|
||||||
|
remainder = ((ulong)state) & 7UL;
|
||||||
|
|
||||||
|
count = 0;
|
||||||
|
while (count < blockSize && !Volatile.Read(ref _limitReached))
|
||||||
|
{
|
||||||
|
bufferSpan[count++] = p;
|
||||||
|
p = _transformP(p, ref remainder);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count == 0)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (count < blockSize && !Volatile.Read(ref _limitReached))
|
newState = ((long)p << 3) | (long)remainder;
|
||||||
|
original = Interlocked.CompareExchange(ref _state, newState, state);
|
||||||
|
if (original == state)
|
||||||
{
|
{
|
||||||
ulong candidate = _currentCandidate;
|
|
||||||
|
|
||||||
if (!EnsurePrimeForCandidate(candidate))
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_hasNextPrime && _nextPrime == candidate)
|
|
||||||
{
|
|
||||||
bufferSpan[count++] = candidate;
|
|
||||||
_hasNextPrime = MoveToNextPrime();
|
|
||||||
if (!_hasNextPrime)
|
|
||||||
{
|
|
||||||
_currentCandidate = _transformP(candidate, ref _currentRemainder);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_currentCandidate = _transformP(candidate, ref _currentRemainder);
|
|
||||||
|
|
||||||
if (Volatile.Read(ref _limitReached))
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private static void PrintResult(ulong currentP, bool searchedMersenne, bool detailedCheck, bool isPerfect)
|
private static void PrintResult(ulong currentP, bool searchedMersenne, bool detailedCheck, bool isPerfect)
|
||||||
|
|||||||
Reference in new issue
Block a user