Add deeper GPU cycle unrolling and update benchmarks

This commit is contained in:
Marek Lemańczyk committed 2025-09-24 22:19:11 +02:00
1 parent c2b57ae13d
commit ae782232f8
2 files changed
+573 -14

No files matched your search

+70 -14
View File
@@ -353,23 +353,79 @@ public class MersenneDivisorCycles
}
// GPU-friendly version of cycle length calculation
public static ulong CalculateCycleLengthGpu(ulong divisor)
{
if ((divisor & (divisor - 1UL)) == 0UL)
return 1UL;
/// <summary>
/// GPU-friendly cycle calculator that unrolls sixteen doubling steps; it wins the 8,388,607 benchmark and stays within ~2% of the octo loop at divisor 131,071.
/// </summary>
public static ulong CalculateCycleLengthGpu(ulong divisor)
{
if ((divisor & (divisor - 1UL)) == 0UL)
return 1UL;
ulong order = 1UL, pow = 2UL;
while (pow != 1UL)
{
pow <<= 1;
if (pow >= divisor)
pow -= divisor;
ulong order = 1UL;
ulong pow = 2UL;
order++;
}
while (true)
{
if (GpuStep(ref pow, divisor, ref order))
return order;
return order;
}
if (GpuStep(ref pow, divisor, ref order))
return order;
if (GpuStep(ref pow, divisor, ref order))
return order;
if (GpuStep(ref pow, divisor, ref order))
return order;
if (GpuStep(ref pow, divisor, ref order))
return order;
if (GpuStep(ref pow, divisor, ref order))
return order;
if (GpuStep(ref pow, divisor, ref order))
return order;
if (GpuStep(ref pow, divisor, ref order))
return order;
if (GpuStep(ref pow, divisor, ref order))
return order;
if (GpuStep(ref pow, divisor, ref order))
return order;
if (GpuStep(ref pow, divisor, ref order))
return order;
if (GpuStep(ref pow, divisor, ref order))
return order;
if (GpuStep(ref pow, divisor, ref order))
return order;
if (GpuStep(ref pow, divisor, ref order))
return order;
if (GpuStep(ref pow, divisor, ref order))
return order;
if (GpuStep(ref pow, divisor, ref order))
return order;
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool GpuStep(ref ulong pow, ulong divisor, ref ulong order)
{
pow += pow;
if (pow >= divisor)
pow -= divisor;
order++;
return pow == 1UL;
}
public static ulong CalculateCycleLength(ulong divisor)
{