Merge pull request #142 from mlemanczyk/codex/analyze-random-byte-generation-performance
Improve Pollard Rho random sampling throughput
This commit is contained in:
1 file changed
+31
-5
@@ -1,9 +1,7 @@
|
||||
using System.Buffers;
|
||||
using System.Buffers.Binary;
|
||||
using System.Collections.Generic;
|
||||
using System.Numerics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using PerfectNumbers.Core.Gpu;
|
||||
@@ -18,6 +16,11 @@ public class MersenneDivisorCycles
|
||||
// Lightweight read-mostly cache for small divisors (<= 4,000,000). 0 => unknown
|
||||
private ulong[]? _smallCycles;
|
||||
|
||||
[ThreadStatic]
|
||||
private static ulong _threadRandomState;
|
||||
|
||||
private static long _randomSeedCounter;
|
||||
|
||||
public static MersenneDivisorCycles Shared { get; } = new MersenneDivisorCycles();
|
||||
|
||||
public MersenneDivisorCycles()
|
||||
@@ -594,9 +597,32 @@ public class MersenneDivisorCycles
|
||||
|
||||
private static ulong NextRandomUInt64()
|
||||
{
|
||||
Span<byte> buffer = stackalloc byte[8];
|
||||
RandomNumberGenerator.Fill(buffer);
|
||||
return BinaryPrimitives.ReadUInt64LittleEndian(buffer);
|
||||
ulong state = _threadRandomState;
|
||||
if (state == 0UL)
|
||||
{
|
||||
state = InitializeThreadRandomState();
|
||||
}
|
||||
|
||||
state ^= state >> 12;
|
||||
state ^= state << 25;
|
||||
state ^= state >> 27;
|
||||
_threadRandomState = state;
|
||||
return state * 2685821657736338717UL;
|
||||
}
|
||||
|
||||
private static ulong InitializeThreadRandomState()
|
||||
{
|
||||
ulong seed = (ulong)Interlocked.Increment(ref _randomSeedCounter);
|
||||
seed += 0x9E3779B97F4A7C15UL;
|
||||
seed = (seed ^ (seed >> 30)) * 0xBF58476D1CE4E5B9UL;
|
||||
seed = (seed ^ (seed >> 27)) * 0x94D049BB133111EBUL;
|
||||
seed ^= seed >> 31;
|
||||
if (seed == 0UL)
|
||||
{
|
||||
seed = 0x9E3779B97F4A7C15UL;
|
||||
}
|
||||
|
||||
return seed;
|
||||
}
|
||||
|
||||
public readonly struct FactorCacheEntry
|
||||
|
||||
Reference in new issue
Block a user