Optimize CPU small prime exponent extraction
This commit is contained in:
1 parent
140c291344
commit
1ce1622388
1 file changed
+70
-14
@@ -1182,28 +1182,19 @@ internal static partial class PrimeOrderCalculator
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Derive the remainder from the quotient to avoid an extra division.
|
ulong primeValue = primeCandidate;
|
||||||
int exponent = 0;
|
int exponent = ExtractSmallPrimeExponent(ref remainingLocal, primeValue);
|
||||||
while (true)
|
if (exponent == 0)
|
||||||
{
|
{
|
||||||
ulong quotient = remainingLocal / primeCandidate;
|
continue;
|
||||||
ulong divisionRemainder = remainingLocal - (quotient * primeCandidate);
|
|
||||||
if (divisionRemainder != 0UL)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
remainingLocal = quotient;
|
|
||||||
exponent++;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Console.WriteLine($"Exponent: {exponent}");
|
|
||||||
if (factorCount >= capacity)
|
if (factorCount >= capacity)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException($"Capacity is smaller than factor count");
|
throw new InvalidOperationException($"Capacity is smaller than factor count");
|
||||||
}
|
}
|
||||||
|
|
||||||
primeTargets[factorCount] = primeCandidate;
|
primeTargets[factorCount] = primeValue;
|
||||||
exponentTargets[factorCount] = exponent;
|
exponentTargets[factorCount] = exponent;
|
||||||
factorCount++;
|
factorCount++;
|
||||||
}
|
}
|
||||||
@@ -1212,6 +1203,71 @@ internal static partial class PrimeOrderCalculator
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
// Unroll the initial divisions because small exponents dominate in practice.
|
||||||
|
private static int ExtractSmallPrimeExponent(ref ulong value, ulong primeValue)
|
||||||
|
{
|
||||||
|
ulong dividend = value;
|
||||||
|
ulong quotient = dividend / primeValue;
|
||||||
|
ulong remainder = dividend - (quotient * primeValue);
|
||||||
|
if (remainder != 0UL)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
dividend = quotient;
|
||||||
|
int exponent = 1;
|
||||||
|
|
||||||
|
quotient = dividend / primeValue;
|
||||||
|
remainder = dividend - (quotient * primeValue);
|
||||||
|
if (remainder != 0UL)
|
||||||
|
{
|
||||||
|
value = dividend;
|
||||||
|
return exponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
dividend = quotient;
|
||||||
|
exponent++;
|
||||||
|
|
||||||
|
quotient = dividend / primeValue;
|
||||||
|
remainder = dividend - (quotient * primeValue);
|
||||||
|
if (remainder != 0UL)
|
||||||
|
{
|
||||||
|
value = dividend;
|
||||||
|
return exponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
dividend = quotient;
|
||||||
|
exponent++;
|
||||||
|
|
||||||
|
quotient = dividend / primeValue;
|
||||||
|
remainder = dividend - (quotient * primeValue);
|
||||||
|
if (remainder != 0UL)
|
||||||
|
{
|
||||||
|
value = dividend;
|
||||||
|
return exponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
dividend = quotient;
|
||||||
|
exponent++;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
quotient = dividend / primeValue;
|
||||||
|
remainder = dividend - (quotient * primeValue);
|
||||||
|
if (remainder != 0UL)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
dividend = quotient;
|
||||||
|
exponent++;
|
||||||
|
}
|
||||||
|
|
||||||
|
value = dividend;
|
||||||
|
return exponent;
|
||||||
|
}
|
||||||
|
|
||||||
private static ulong PopulateSmallPrimeFactorsCpu(ulong value, uint limit, Dictionary<ulong, int> counts)
|
private static ulong PopulateSmallPrimeFactorsCpu(ulong value, uint limit, Dictionary<ulong, int> counts)
|
||||||
{
|
{
|
||||||
ulong remaining = value;
|
ulong remaining = value;
|
||||||
|
|||||||
Reference in new issue
Block a user