Calculation switched to typical O(N)

This commit is contained in:
mlemanczyk committed 2025-10-12 18:23:06 +02:00
1 parent 7562f14b1c
commit d555e157f6
1 file changed
+44 -44
@@ -1812,56 +1812,56 @@ internal static partial class PrimeOrderGpuHeuristics
{ {
ulong exponent = exponents[index]; ulong exponent = exponents[index];
ulong modulus = divisor.Modulus; ulong modulus = divisor.Modulus;
ulong nPrime = divisor.NPrime; // ulong nPrime = divisor.NPrime;
ulong result = divisor.MontgomeryOne; // ulong result = divisor.MontgomeryOne;
ulong baseValue = divisor.MontgomeryTwo; // ulong baseValue = divisor.MontgomeryTwo;
ulong remainingExponent = exponent; // ulong remainingExponent = exponent;
if (remainingExponent == 0UL) // if (remainingExponent == 0UL)
{ // {
remainders[index] = result.MontgomeryMultiply(1UL, modulus, nPrime); // remainders[index] = result.MontgomeryMultiply(1UL, modulus, nPrime);
return; // return;
} // }
while (remainingExponent != 0UL) // while (remainingExponent != 0UL)
{ // {
if ((remainingExponent & 1UL) != 0UL) // if ((remainingExponent & 1UL) != 0UL)
{ // {
result = result.MontgomeryMultiply(baseValue, modulus, nPrime); // result = result.MontgomeryMultiply(baseValue, modulus, nPrime);
} // }
remainingExponent >>= 1; // remainingExponent >>= 1;
if (remainingExponent == 0UL) // if (remainingExponent == 0UL)
{ // {
break; // break;
} // }
// Reusing baseValue to hold base^2 so we avoid allocating another register for the squared term. // // Reusing baseValue to hold base^2 so we avoid allocating another register for the squared term.
baseValue = baseValue.MontgomeryMultiply(baseValue, modulus, nPrime); // baseValue = baseValue.MontgomeryMultiply(baseValue, modulus, nPrime);
} // }
remainders[index] = result.MontgomeryMultiply(1UL, modulus, nPrime); // remainders[index] = result.MontgomeryMultiply(1UL, modulus, nPrime);
// Plain modular exponentiation without Montgomery reduction kept for reference. // Plain modular exponentiation without Montgomery reduction kept for reference.
// ulong plainResult = 1UL % modulus; ulong plainResult = 1UL;// % modulus;
// ulong plainBase = 2UL % modulus; ulong plainBase = 2UL;// % modulus;
// ulong plainExponent = exponent; while (exponent != 0UL)
// while (plainExponent != 0UL) {
// { if ((exponent & 1UL) != 0UL)
// if ((plainExponent & 1UL) != 0UL) {
// { plainResult = (plainResult * plainBase) % modulus;
// plainResult = (plainResult * plainBase) % modulus; }
// }
// exponent >>= 1;
// plainExponent >>= 1; if (exponent == 0UL)
// if (plainExponent == 0UL) {
// { break;
// break; }
// }
// plainBase = (plainBase * plainBase) % modulus;
// plainBase = (plainBase * plainBase) % modulus; }
// }
// remainders[index] = plainResult; remainders[index] = plainResult;
} }
private static Action<AcceleratorStream, Index1D, ArrayView1D<GpuUInt128, Stride1D.Dense>, GpuUInt128, ArrayView1D<GpuUInt128, Stride1D.Dense>> GetPow2ModWideKernel(Accelerator accelerator) private static Action<AcceleratorStream, Index1D, ArrayView1D<GpuUInt128, Stride1D.Dense>, GpuUInt128, ArrayView1D<GpuUInt128, Stride1D.Dense>> GetPow2ModWideKernel(Accelerator accelerator)