Optimize primorial computation.

master
mikaelh 2013-07-21 12:58:26 +03:00
parent cfcdc3112a
commit 9bd1366f8c
3 changed files with 47 additions and 8 deletions

View File

@ -4607,8 +4607,7 @@ void static BitcoinMiner(CWallet *pwallet)
unsigned int nTriedMultiplier = 0;
// Primecoin: try to find hash divisible by primorial
mpz_class mpzHashFactor;
Primorial(nPrimorialHashFactor, mpzHashFactor);
unsigned int nHashFactor = PrimorialFast(nPrimorialHashFactor);
// Based on mustyoshi's patch from https://bitcointalk.org/index.php?topic=251850.msg2689981#msg2689981
uint256 phash;
@ -4626,7 +4625,7 @@ void static BitcoinMiner(CWallet *pwallet)
// Check that the hash is divisible by the fixed primorial
mpz_set_uint256(mpzHash.get_mpz_t(), phash);
if (!mpz_divisible_p(mpzHash.get_mpz_t(), mpzHashFactor.get_mpz_t())) {
if (!mpz_divisible_ui_p(mpzHash.get_mpz_t(), nHashFactor)) {
pblock->nNonce++;
continue;
}
@ -4660,7 +4659,7 @@ void static BitcoinMiner(CWallet *pwallet)
Primorial(nPrimorialMultiplier, mpzPrimorial);
// Primecoin: adjust round primorial so that the generated prime candidates meet the minimum
mpz_class mpzMultiplierMin = mpzPrimeMin * mpzHashFactor / mpzHash + 1;
mpz_class mpzMultiplierMin = mpzPrimeMin * nHashFactor / mpzHash + 1;
while (mpzPrimorial < mpzMultiplierMin)
{
if (!PrimeTableGetNextPrime(nPrimorialMultiplier))
@ -4668,8 +4667,8 @@ void static BitcoinMiner(CWallet *pwallet)
Primorial(nPrimorialMultiplier, mpzPrimorial);
}
mpz_class mpzFixedMultiplier;
if (mpzPrimorial > mpzHashFactor) {
mpzFixedMultiplier = mpzPrimorial / mpzHashFactor;
if (mpzPrimorial > nHashFactor) {
mpzFixedMultiplier = mpzPrimorial / nHashFactor;
} else {
mpzFixedMultiplier = 1;
}

View File

@ -77,14 +77,51 @@ bool PrimeTableGetPreviousPrime(unsigned int& p)
// Compute Primorial number p#
void Primorial(unsigned int p, mpz_class& mpzPrimorial)
{
mpzPrimorial = 1;
BOOST_FOREACH(unsigned int nPrime, vPrimes)
unsigned long nPrimorial = 1;
unsigned int i;
if (sizeof(unsigned long) >= 8)
{
// Fast 64-bit loop if possible
for (i = 0; i < 15; i++)
{
unsigned int nPrime = vPrimes[i];
if (nPrime > p) break;
nPrimorial *= nPrime;
}
}
else
{
// Fast 32-bit loop first
for (i = 0; i < 9; i++)
{
unsigned int nPrime = vPrimes[i];
if (nPrime > p) break;
nPrimorial *= nPrime;
}
}
mpzPrimorial = nPrimorial;
for (; i < vPrimes.size(); i++)
{
unsigned int nPrime = vPrimes[i];
if (nPrime > p) break;
mpzPrimorial *= nPrime;
}
}
// Compute Primorial number p#
// Fast 32-bit version assuming that p <= 23
unsigned int PrimorialFast(unsigned int p)
{
unsigned int nPrimorial = 1;
BOOST_FOREACH(unsigned int nPrime, vPrimes)
{
if (nPrime > p) break;
nPrimorial *= nPrime;
}
return nPrimorial;
}
// Compute first primorial number greater than or equal to pn
void PrimorialAt(mpz_class& bn, mpz_class& mpzPrimorial)
{

View File

@ -38,6 +38,9 @@ bool PrimeTableGetPreviousPrime(unsigned int& p);
// Compute primorial number p#
void Primorial(unsigned int p, mpz_class& mpzPrimorial);
// Compute Primorial number p#
// Fast 32-bit version assuming that p <= 23
unsigned int PrimorialFast(unsigned int p);
// Compute the first primorial number greater than or equal to bn
void PrimorialAt(mpz_class& bn, mpz_class& mpzPrimorial);