Extract divisor validator and rename legacy CPU prime helper
This commit is contained in:
1 parent
1e5eadac34
commit
3758524450
11 files changed
+67
-61
No files matched your search
@@ -105,7 +105,7 @@ public class PrimeTesterBenchmarks
|
|||||||
|
|
||||||
for (int i = 0; i < values.Length; i++)
|
for (int i = 0; i < values.Length; i++)
|
||||||
{
|
{
|
||||||
if (PrimeTester.IsPrimeCp(values[i], cancellationToken))
|
if (PrimeTester.IsPrimeCpu(values[i], cancellationToken))
|
||||||
{
|
{
|
||||||
primeCount++;
|
primeCount++;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
|
namespace PerfectNumbers.Core;
|
||||||
|
|
||||||
|
internal static class DivisorGenerator
|
||||||
|
{
|
||||||
|
private const ushort DecimalMaskWhenLastIsSeven = (1 << 3) | (1 << 7) | (1 << 9);
|
||||||
|
private const ushort DecimalMaskOtherwise = (1 << 1) | (1 << 3) | (1 << 9);
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static bool IsValidDivisor(
|
||||||
|
byte remainder10,
|
||||||
|
byte remainder8,
|
||||||
|
byte remainder3,
|
||||||
|
byte remainder5,
|
||||||
|
byte remainder7,
|
||||||
|
byte remainder11,
|
||||||
|
LastDigit lastDigit)
|
||||||
|
{
|
||||||
|
ushort decimalMask = lastDigit == LastDigit.Seven ? DecimalMaskWhenLastIsSeven : DecimalMaskOtherwise;
|
||||||
|
if (((decimalMask >> remainder10) & 1) == 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remainder8 != 1 && remainder8 != 7)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remainder3 == 0 || remainder5 == 0 || remainder7 == 0 || remainder11 == 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -263,7 +263,7 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv
|
|||||||
{
|
{
|
||||||
ulong candidate = (ulong)nextDivisor128;
|
ulong candidate = (ulong)nextDivisor128;
|
||||||
|
|
||||||
if (CandidatePassesHeuristics(localRemainder10, localRemainder8, localRemainder3, localRemainder5, localRemainder7, localRemainder11, lastDigit))
|
if (DivisorGenerator.IsValidDivisor(localRemainder10, localRemainder8, localRemainder3, localRemainder5, localRemainder7, localRemainder11, lastDigit))
|
||||||
{
|
{
|
||||||
filteredStorage[filteredCount++] = candidate;
|
filteredStorage[filteredCount++] = candidate;
|
||||||
}
|
}
|
||||||
@@ -378,38 +378,6 @@ public sealed class MersenneNumberDivisorByDivisorGpuTester : IMersenneNumberDiv
|
|||||||
return computedCycle;
|
return computedCycle;
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
private static bool CandidatePassesHeuristics(
|
|
||||||
byte remainder10,
|
|
||||||
byte remainder8,
|
|
||||||
byte remainder3,
|
|
||||||
byte remainder5,
|
|
||||||
byte remainder7,
|
|
||||||
byte remainder11,
|
|
||||||
LastDigit lastDigit)
|
|
||||||
{
|
|
||||||
const ushort DecimalMaskWhenLastIsSeven = (1 << 3) | (1 << 7) | (1 << 9);
|
|
||||||
const ushort DecimalMaskOtherwise = (1 << 1) | (1 << 3) | (1 << 9);
|
|
||||||
|
|
||||||
ushort decimalMask = lastDigit == LastDigit.Seven ? DecimalMaskWhenLastIsSeven : DecimalMaskOtherwise;
|
|
||||||
if (((decimalMask >> remainder10) & 1) == 0)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (remainder8 != 1 && remainder8 != 7)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (remainder3 == 0 || remainder5 == 0 || remainder7 == 0 || remainder11 == 0)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private static byte AddMod(byte value, byte delta, byte modulus)
|
private static byte AddMod(byte value, byte delta, byte modulus)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -394,9 +394,9 @@ public class MersenneDivisorCycles
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Benchmark PrimeTester.IsPrimeCp against Open.Numeric.Primes on the EvenPerfectBitScanner workloads to confirm the faster option for wide composites.
|
// TODO: Benchmark PrimeTester.IsPrimeCpu against Open.Numeric.Primes on the EvenPerfectBitScanner workloads to confirm the faster option for wide composites.
|
||||||
// if (HeuristicPrimeTester.Exclusive.IsPrimeCpu(remaining, CancellationToken.None))
|
// if (HeuristicPrimeTester.Exclusive.IsPrimeCpu(remaining, CancellationToken.None))
|
||||||
if (PrimeTester.IsPrimeCp(remaining, CancellationToken.None))
|
if (PrimeTester.IsPrimeCpu(remaining, CancellationToken.None))
|
||||||
{
|
{
|
||||||
AddFactor(counts, remaining);
|
AddFactor(counts, remaining);
|
||||||
return true;
|
return true;
|
||||||
@@ -929,7 +929,7 @@ public class MersenneDivisorCycles
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if (!skipPrimeOrderHeuristic && HeuristicPrimeTester.Exclusive.IsPrimeCpu(divisor, CancellationToken.None))
|
// if (!skipPrimeOrderHeuristic && HeuristicPrimeTester.Exclusive.IsPrimeCpu(divisor, CancellationToken.None))
|
||||||
if (!skipPrimeOrderHeuristic && PrimeTester.IsPrimeCp(divisor, CancellationToken.None))
|
if (!skipPrimeOrderHeuristic && PrimeTester.IsPrimeCpu(divisor, CancellationToken.None))
|
||||||
{
|
{
|
||||||
ulong computedOrder = PrimeOrderCalculator.Calculate(
|
ulong computedOrder = PrimeOrderCalculator.Calculate(
|
||||||
divisor,
|
divisor,
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ public static class MersennePrimeFactorTester
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if (!HeuristicPrimeTester.Exclusive.IsPrimeCpu(q, ct))
|
// if (!HeuristicPrimeTester.Exclusive.IsPrimeCpu(q, ct))
|
||||||
if (!PrimeTester.IsPrimeCp(q, ct))
|
if (!PrimeTester.IsPrimeCpu(q, ct))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -235,7 +235,7 @@ public static class MersennePrimeFactorTester
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if (HeuristicPrimeTester.Exclusive.IsPrimeCpu(m, ct))
|
// if (HeuristicPrimeTester.Exclusive.IsPrimeCpu(m, ct))
|
||||||
if (PrimeTester.IsPrimeCp(m, ct))
|
if (PrimeTester.IsPrimeCpu(m, ct))
|
||||||
{
|
{
|
||||||
dict[m] = 1;
|
dict[m] = 1;
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -516,7 +516,7 @@ internal static partial class PrimeOrderCalculator
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (!PrimeTester.IsPrimeCp(orderFactors.Cofactor, CancellationToken.None))
|
// if (!PrimeTester.IsPrimeCpu(orderFactors.Cofactor, CancellationToken.None))
|
||||||
if (!orderFactors.CofactorIsPrime)
|
if (!orderFactors.CofactorIsPrime)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -1123,8 +1123,8 @@ internal static partial class PrimeOrderCalculator
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
// bool isPrime = primeTester.HeuristicIsPrimeGpu(composite);
|
// bool isPrime = primeTester.HeuristicIsPrimeGpu(composite);
|
||||||
// bool isPrime = PrimeTester.IsPrimeCp(composite, CancellationToken.None);
|
// bool isPrime = PrimeTester.IsPrimeCpu(composite, CancellationToken.None);
|
||||||
bool isPrime = PrimeTester.IsPrimeCp(composite, CancellationToken.None);
|
bool isPrime = PrimeTester.IsPrimeCpu(composite, CancellationToken.None);
|
||||||
// bool isPrime = Open.Numeric.Primes.Prime.Numbers.IsPrime(composite);
|
// bool isPrime = Open.Numeric.Primes.Prime.Numbers.IsPrime(composite);
|
||||||
|
|
||||||
if (isPrime)
|
if (isPrime)
|
||||||
@@ -1186,8 +1186,8 @@ internal static partial class PrimeOrderCalculator
|
|||||||
if (!entry.HasKnownPrimality)
|
if (!entry.HasKnownPrimality)
|
||||||
{
|
{
|
||||||
// bool isPrime = primeTester.HeuristicIsPrimeGpu(composite);
|
// bool isPrime = primeTester.HeuristicIsPrimeGpu(composite);
|
||||||
// bool isPrime = PrimeTester.IsPrimeCp(composite, CancellationToken.None);
|
// bool isPrime = PrimeTester.IsPrimeCpu(composite, CancellationToken.None);
|
||||||
bool isPrime = PrimeTester.IsPrimeCp(composite, CancellationToken.None);
|
bool isPrime = PrimeTester.IsPrimeCpu(composite, CancellationToken.None);
|
||||||
// bool isPrime = Open.Numeric.Primes.Prime.Numbers.IsPrime(composite);
|
// bool isPrime = Open.Numeric.Primes.Prime.Numbers.IsPrime(composite);
|
||||||
|
|
||||||
entry = entry.WithPrimality(isPrime);
|
entry = entry.WithPrimality(isPrime);
|
||||||
@@ -1219,8 +1219,8 @@ internal static partial class PrimeOrderCalculator
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// cofactorIsPrime = primeTester.HeuristicIsPrimeGpu(cofactor);
|
// cofactorIsPrime = primeTester.HeuristicIsPrimeGpu(cofactor);
|
||||||
// cofactorIsPrime = PrimeTester.IsPrimeCp(cofactor, CancellationToken.None);
|
// cofactorIsPrime = PrimeTester.IsPrimeCpu(cofactor, CancellationToken.None);
|
||||||
cofactorIsPrime = PrimeTester.IsPrimeCp(cofactor, CancellationToken.None);
|
cofactorIsPrime = PrimeTester.IsPrimeCpu(cofactor, CancellationToken.None);
|
||||||
// cofactorIsPrime = Open.Numeric.Primes.Prime.Numbers.IsPrime(cofactor);
|
// cofactorIsPrime = Open.Numeric.Primes.Prime.Numbers.IsPrime(cofactor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1752,8 +1752,8 @@ internal static partial class PrimeOrderCalculator
|
|||||||
PrimeTester primeTester = PrimeTester.Exclusive;
|
PrimeTester primeTester = PrimeTester.Exclusive;
|
||||||
|
|
||||||
// bool isPrime = primeTester.HeuristicIsPrimeGpu(value);
|
// bool isPrime = primeTester.HeuristicIsPrimeGpu(value);
|
||||||
// bool isPrime = PrimeTester.IsPrimeCp(value, CancellationToken.None);
|
// bool isPrime = PrimeTester.IsPrimeCpu(value, CancellationToken.None);
|
||||||
bool isPrime = PrimeTester.IsPrimeCp(value, CancellationToken.None);
|
bool isPrime = PrimeTester.IsPrimeCpu(value, CancellationToken.None);
|
||||||
// bool isPrime = Open.Numeric.Primes.Prime.Numbers.IsPrime(value);
|
// bool isPrime = Open.Numeric.Primes.Prime.Numbers.IsPrime(value);
|
||||||
if (!knownComposite && isPrime)
|
if (!knownComposite && isPrime)
|
||||||
{
|
{
|
||||||
@@ -1765,8 +1765,8 @@ internal static partial class PrimeOrderCalculator
|
|||||||
ulong quotient = value / factor;
|
ulong quotient = value / factor;
|
||||||
|
|
||||||
// isPrime = primeTester.HeuristicIsPrimeGpu(factor);
|
// isPrime = primeTester.HeuristicIsPrimeGpu(factor);
|
||||||
// isPrime = PrimeTester.IsPrimeCp(factor, CancellationToken.None);
|
// isPrime = PrimeTester.IsPrimeCpu(factor, CancellationToken.None);
|
||||||
isPrime = PrimeTester.IsPrimeCp(factor, CancellationToken.None);
|
isPrime = PrimeTester.IsPrimeCpu(factor, CancellationToken.None);
|
||||||
// isPrime = Open.Numeric.Primes.Prime.Numbers.IsPrime(factor);
|
// isPrime = Open.Numeric.Primes.Prime.Numbers.IsPrime(factor);
|
||||||
if (isPrime)
|
if (isPrime)
|
||||||
{
|
{
|
||||||
@@ -1797,8 +1797,8 @@ internal static partial class PrimeOrderCalculator
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// isPrime = primeTester.HeuristicIsPrimeGpu(quotient);
|
// isPrime = primeTester.HeuristicIsPrimeGpu(quotient);
|
||||||
// isPrime = PrimeTester.IsPrimeCp(quotient, CancellationToken.None);
|
// isPrime = PrimeTester.IsPrimeCpu(quotient, CancellationToken.None);
|
||||||
isPrime = PrimeTester.IsPrimeCp(quotient, CancellationToken.None);
|
isPrime = PrimeTester.IsPrimeCpu(quotient, CancellationToken.None);
|
||||||
// isPrime = Open.Numeric.Primes.Prime.Numbers.IsPrime(quotient);
|
// isPrime = Open.Numeric.Primes.Prime.Numbers.IsPrime(quotient);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -956,7 +956,7 @@ internal static partial class PrimeOrderCalculator
|
|||||||
if (value <= ulong.MaxValue)
|
if (value <= ulong.MaxValue)
|
||||||
{
|
{
|
||||||
// return HeuristicPrimeTester.Exclusive.IsPrimeCpu((ulong)value, CancellationToken.None);
|
// return HeuristicPrimeTester.Exclusive.IsPrimeCpu((ulong)value, CancellationToken.None);
|
||||||
return PrimeTester.IsPrimeCp((ulong)value, CancellationToken.None);
|
return PrimeTester.IsPrimeCpu((ulong)value, CancellationToken.None);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((value & UInt128.One) == UInt128.Zero)
|
if ((value & UInt128.One) == UInt128.Zero)
|
||||||
|
|||||||
@@ -93,10 +93,10 @@ public sealed class PrimeTester
|
|||||||
bool gpuReportedPrime = !forceCpu && !belowGpuRange && outFlags[0] != 0;
|
bool gpuReportedPrime = !forceCpu && !belowGpuRange && outFlags[0] != 0;
|
||||||
bool requiresCpuFallback = forceCpu || belowGpuRange || !gpuReportedPrime;
|
bool requiresCpuFallback = forceCpu || belowGpuRange || !gpuReportedPrime;
|
||||||
|
|
||||||
return requiresCpuFallback ? IsPrimeCp(n, ct) : true;
|
return requiresCpuFallback ? IsPrimeCpu(n, ct) : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsPrimeCp(ulong n, CancellationToken ct)
|
public static bool IsPrimeCpu(ulong n, CancellationToken ct)
|
||||||
{
|
{
|
||||||
// Preserve the legacy entry point for callers that bypass the thread-local caches.
|
// Preserve the legacy entry point for callers that bypass the thread-local caches.
|
||||||
return Exclusive.IsPrime(n, ct);
|
return Exclusive.IsPrime(n, ct);
|
||||||
|
|||||||
@@ -64,12 +64,12 @@ public bool IsPrimeGpu(ulong n, CancellationToken ct)
|
|||||||
bool gpuReportedPrime = !forceCpu && !belowGpuRange && outFlags[0] != 0;
|
bool gpuReportedPrime = !forceCpu && !belowGpuRange && outFlags[0] != 0;
|
||||||
bool requiresCpuFallback = forceCpu || belowGpuRange || !gpuReportedPrime;
|
bool requiresCpuFallback = forceCpu || belowGpuRange || !gpuReportedPrime;
|
||||||
|
|
||||||
return requiresCpuFallback ? IsPrimeCp(n, ct) : true;
|
return requiresCpuFallback ? IsPrimeCpu(n, ct) : true;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
internal static bool IsPrimeCp(ulong n, CancellationToken ct)
|
internal static bool IsPrimeCpu(ulong n, CancellationToken ct)
|
||||||
{
|
{
|
||||||
bool isTwo = n == 2UL;
|
bool isTwo = n == 2UL;
|
||||||
bool isOdd = (n & 1UL) != 0UL;
|
bool isOdd = (n & 1UL) != 0UL;
|
||||||
@@ -113,7 +113,7 @@ internal static bool IsPrimeCp(ulong n, CancellationToken ct)
|
|||||||
|
|
||||||
The plan incorporates the updated divisor-class heuristics (Groups A/B, wheels, residue priorities) and connects them to both CPU and GPU execution, including every by-divisor integration point. Items already completed are marked with `[done]`.
|
The plan incorporates the updated divisor-class heuristics (Groups A/B, wheels, residue priorities) and connects them to both CPU and GPU execution, including every by-divisor integration point. Items already completed are marked with `[done]`.
|
||||||
|
|
||||||
1. [done] **Snapshot current implementations** – preserve `IsPrimeGpu` and `IsPrimeCp` as references for regression comparisons and migration checkpoints (see Section 2).
|
1. [done] **Snapshot current implementations** – preserve `IsPrimeGpu` and `IsPrimeCpu` as references for regression comparisons and migration checkpoints (see Section 2).
|
||||||
2. [done] **Introduce placeholder heuristic entry points** – add `IsPrimeCpu` and `IsPrimeGpu` by copying the current internal and GPU methods so subsequent commits can iterate without disrupting legacy behavior.
|
2. [done] **Introduce placeholder heuristic entry points** – add `IsPrimeCpu` and `IsPrimeGpu` by copying the current internal and GPU methods so subsequent commits can iterate without disrupting legacy behavior.
|
||||||
3. [done] **Design shared heuristic scaffolding**
|
3. [done] **Design shared heuristic scaffolding**
|
||||||
* [done] Added `HeuristicPrimeSieves` to precompute 4M-entry Group A/B divisor tables so heuristic prime checks reuse cached sequences without regenerating wheel steps at runtime; the enumerator remains available for residue-driven consumers.
|
* [done] Added `HeuristicPrimeSieves` to precompute 4M-entry Group A/B divisor tables so heuristic prime checks reuse cached sequences without regenerating wheel steps at runtime; the enumerator remains available for residue-driven consumers.
|
||||||
@@ -140,7 +140,7 @@ The plan incorporates the updated divisor-class heuristics (Groups A/B, wheels,
|
|||||||
* [done] Streamed GPU batches from the same enumerator and Montgomery preparation data, removing the filtered-divisor scratch arrays while continuing to feed the existing kernel and hit bookkeeping.
|
* [done] Streamed GPU batches from the same enumerator and Montgomery preparation data, removing the filtered-divisor scratch arrays while continuing to feed the existing kernel and hit bookkeeping.
|
||||||
9. [done] **Route legacy prime checks through heuristics**
|
9. [done] **Route legacy prime checks through heuristics**
|
||||||
* [done] Introduce `HeuristicPrimeTester` so heuristic CPU/GPU checks live alongside the legacy `PrimeTester` implementations while callers opt in explicitly.
|
* [done] Introduce `HeuristicPrimeTester` so heuristic CPU/GPU checks live alongside the legacy `PrimeTester` implementations while callers opt in explicitly.
|
||||||
* [done] Maintain legacy paths for benchmarking via `PrimeTester.IsPrimeCp`, `PrimeTester.Exclusive.IsPrimeGpu`, and the explicit `HeuristicPrimeTester` entry points so benchmark harnesses can compare behaviours without runtime switches.
|
* [done] Maintain legacy paths for benchmarking via `PrimeTester.IsPrimeCpu`, `PrimeTester.Exclusive.IsPrimeGpu`, and the explicit `HeuristicPrimeTester` entry points so benchmark harnesses can compare behaviours without runtime switches.
|
||||||
10. **Validation and benchmarking**
|
10. **Validation and benchmarking**
|
||||||
* Create targeted unit tests covering boundary cases for Group A/B transitions, wheel enumerations, residue deltas, and the stop-on-hit behaviour.
|
* Create targeted unit tests covering boundary cases for Group A/B transitions, wheel enumerations, residue deltas, and the stop-on-hit behaviour.
|
||||||
* Expand GPU test harnesses to assert equivalence between CPU/GPU heuristics on sampled composite and prime inputs and to verify the residue-stream contract with by-divisor sessions.
|
* Expand GPU test harnesses to assert equivalence between CPU/GPU heuristics on sampled composite and prime inputs and to verify the residue-stream contract with by-divisor sessions.
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ No other endings are allowed or reordered.
|
|||||||
## Default Prime Tester Entry Points
|
## Default Prime Tester Entry Points
|
||||||
|
|
||||||
* `PrimeTester.IsPrime` and `PrimeTester.IsPrimeGpu` continue to run the legacy trial-division and GPU sieve paths. Use `HeuristicPrimeTester` when the heuristic CPU/GPU flow is required.
|
* `PrimeTester.IsPrime` and `PrimeTester.IsPrimeGpu` continue to run the legacy trial-division and GPU sieve paths. Use `HeuristicPrimeTester` when the heuristic CPU/GPU flow is required.
|
||||||
* `HeuristicPrimeTester` always executes the heuristic CPU/GPU implementations; opt into the legacy paths by calling `PrimeTester.IsPrimeCp` or `PrimeTester.Exclusive.IsPrimeGpu` directly.
|
* `HeuristicPrimeTester` always executes the heuristic CPU/GPU implementations; opt into the legacy paths by calling `PrimeTester.IsPrimeCpu` or `PrimeTester.Exclusive.IsPrimeGpu` directly.
|
||||||
* Benchmark harnesses can compare behaviours by calling the legacy helpers on `PrimeTester` alongside the heuristic equivalents on `HeuristicPrimeTester`.
|
* Benchmark harnesses can compare behaviours by calling the legacy helpers on `PrimeTester` alongside the heuristic equivalents on `HeuristicPrimeTester`.
|
||||||
|
|
||||||
## Integration with the By-Divisor Pipeline
|
## Integration with the By-Divisor Pipeline
|
||||||
|
|||||||
+1
-1
@@ -18,7 +18,7 @@ Divisor Cycle Cache & Generation
|
|||||||
- PerfectNumbers.Core/UInt128Extensions.cs:372: If the cache lacks this cycle, immediately schedule the configured device (GPU by default) to compute it on the fly and skip inserting it into the cache so wide-order factoring can still leverage cycle stepping without breaching the memory cap or introducing extra synchronization.
|
- PerfectNumbers.Core/UInt128Extensions.cs:372: If the cache lacks this cycle, immediately schedule the configured device (GPU by default) to compute it on the fly and skip inserting it into the cache so wide-order factoring can still leverage cycle stepping without breaching the memory cap or introducing extra synchronization.
|
||||||
|
|
||||||
Primality & Order Screening
|
Primality & Order Screening
|
||||||
- PerfectNumbers.Core/MersenneDivisorCycles.cs:477: Benchmark PrimeTester.IsPrimeCp against Open.Numeric.Primes on the EvenPerfectBitScanner workloads to confirm the faster option for wide composites.
|
- PerfectNumbers.Core/MersenneDivisorCycles.cs:477: Benchmark PrimeTester.IsPrimeCpu against Open.Numeric.Primes on the EvenPerfectBitScanner workloads to confirm the faster option for wide composites.
|
||||||
- PerfectNumbers.Core/ULongExtensions.cs:119: When the shared cycle snapshot cannot serve this divisor, trigger an on-demand GPU computation (respecting the configured device) without promoting the result into the cache so the order calculator still benefits from cycle stepping while keeping the single-block memory plan intact.
|
- PerfectNumbers.Core/ULongExtensions.cs:119: When the shared cycle snapshot cannot serve this divisor, trigger an on-demand GPU computation (respecting the configured device) without promoting the result into the cache so the order calculator still benefits from cycle stepping while keeping the single-block memory plan intact.
|
||||||
- PerfectNumbers.Core/ULongExtensions.cs:132: Replace this `%` driven factor peeling with the divisor-cycle aware factoring helper so large orders reuse the cached remainders highlighted in the latest divisor-cycle benchmarks instead of recomputing slow modulo checks.
|
- PerfectNumbers.Core/ULongExtensions.cs:132: Replace this `%` driven factor peeling with the divisor-cycle aware factoring helper so large orders reuse the cached remainders highlighted in the latest divisor-cycle benchmarks instead of recomputing slow modulo checks.
|
||||||
- PerfectNumbers.Core/ULongExtensions.cs:279: Swap this modulo check for the shared small-prime cycle filter once the divisor-cycle cache is mandatory, matching the PrimeTester improvements noted in the CPU sieve benchmarks.
|
- PerfectNumbers.Core/ULongExtensions.cs:279: Swap this modulo check for the shared small-prime cycle filter once the divisor-cycle cache is mandatory, matching the PrimeTester improvements noted in the CPU sieve benchmarks.
|
||||||
|
|||||||
Reference in new issue
Block a user