예제 #1
0
void cSieve_prepare(mpz_class& mpzFixedMultiplier, uint32 chainLength)
{
	uint32 sieveSize = (nMaxSieveSize+7)&~7; // align to 8
	// todo: Make sure the sieve doesnt crash when the difficulty changes
	if( cSieve == NULL || cSieve->chainLength != chainLength )
	{
		if( cSieve == NULL )
		{
			cSieve = (continuousSieve_t*)malloc(sizeof(continuousSieve_t));
			memset(cSieve, 0x00, sizeof(continuousSieve_t));
		}
		// free bitmasks if the size changed
		if( cSieve->chainLength != chainLength )
		{
			if( cSieve->layerMaskC1 )
			{
				free(cSieve->layerMaskC1);
				free(cSieve->layerMaskC2);
				//free(cSieve->layerMaskBT);
				cSieve->layerMaskC1 = NULL;
				cSieve->layerMaskC2 = NULL;
				//cSieve->layerMaskBT = NULL;
			}
		}
		// alloc sieve mask
		cSieve->sieveSize = sieveSize;
		cSieve->chainLength = chainLength;
		cSieve->maskBytes = (sieveSize+7)/8;
		uint32 chainMaskSize = cSieve->maskBytes * chainLength;
		if( cSieve->layerMaskC1 == NULL )
		{
			cSieve->layerMaskC1 = (uint8*)malloc(chainMaskSize);
			cSieve->layerMaskC2 = (uint8*)malloc(chainMaskSize);
			//cSieve->layerMaskBT = (uint8*)malloc(chainMaskSize);
		}
		// reset sieve
		memset(cSieve->layerMaskC1, 0x00, chainMaskSize);
		memset(cSieve->layerMaskC2, 0x00, chainMaskSize);
		//memset(cSieve->layerMaskBT, 0x00, chainMaskSize);
	}
	// alloc prime factor base table
	if( cSieve->primeFactorBase == NULL )
	{
		unsigned int nPrimes = 0;
		if( nSievePercentage <= 100 )
			nPrimes = (uint64)vPrimes.size() * (uint64)nSievePercentage / 100ULL;
		else
			nPrimes = vPrimes.size(); // use the whole array to avoid rounding problems and out-of-bounds access
		cSieve->numPrimeFactors = nPrimes;//50000;
		cSieve->primeFactorBase = (cPrimeFactor_t*)malloc(sizeof(cPrimeFactor_t)*cSieve->numPrimeFactors);
		for(uint32 i=0; i<cSieve->numPrimeFactors; i++)
		{
			cSieve->primeFactorBase[i].twoInverse = single_modinv(2, vPrimes[i]);
		}
	}
	// calculate fixed inverse
	mpz_class mpzF, mpzTemp;
	for(uint32 i=0; i<cSieve->numPrimeFactors; i++)
	{
		uint32 p = vPrimes[i];
		uint32 fixedFactorMod = mpz_mod_ui(mpzTemp.get_mpz_t(), mpzFixedMultiplier.get_mpz_t(), p);
		cSieve->primeFactorBase[i].mod = fixedFactorMod; 
		cSieve->primeFactorBase[i].base = single_modinv(fixedFactorMod, p); 
	}
	// do sieving for the first nChainLength layers
	//for(uint32 t=0; t<cSieve->chainLength; t++)
	//for(uint32 t=0; t<cSieve->chainLength; t++)
	cSieve->mpzFixedMultiplier = mpzFixedMultiplier;
	for(uint32 t=0; t<cSieve->chainLength; t++)
	{
		mpzF = mpzFixedMultiplier;
		uint8* maskC1 = cSieve->layerMaskC1+t*cSieve->maskBytes; 
		uint8* maskC2 = cSieve->layerMaskC2+t*cSieve->maskBytes; 
		for(uint32 i=0; i<cSieve->numPrimeFactors; i++)
		{
			if( cSieve->primeFactorBase[i].mod == 0 )
				continue;
			uint32 p = vPrimes[i];
			/*uint32 fixedFactorMod = mpz_mod_ui(mpzTemp.get_mpz_t(), mpzF.get_mpz_t(), p);
			uint32 fixedInverseU32 = single_modinv(fixedFactorMod, p); 
			*///uint32 fixedInverseTwo = single_modinv(2, p);
			
			// mark all cunningham chains of first kind
			uint32 nSolvedMultiplier = cSieve->primeFactorBase[i].base;
			while( nSolvedMultiplier < cSieve->sieveSize )
			{
				maskC1[nSolvedMultiplier>>3] |= (1<<(nSolvedMultiplier&7));
				nSolvedMultiplier += p;
			}
			// mark all cunningham chains of second kind
			uint64 nSolvedMultiplier64 = (uint64)cSieve->primeFactorBase[i].base * (uint64)(p-1); // tested and correct
			nSolvedMultiplier64 %= (uint64)p;

			nSolvedMultiplier = (uint32)nSolvedMultiplier64;
			while( nSolvedMultiplier < cSieve->sieveSize )
			{
				maskC2[nSolvedMultiplier>>3] |= (1<<(nSolvedMultiplier&7));			
				nSolvedMultiplier += p;
			}
			// apply *2 factor to prime base
			//cSieve->primeFactorBase[i].base = (cSieve->primeFactorBase[i].base*cSieve->primeFactorBase[i].twoInverse)%p;
			cSieve->primeFactorBase[i].base = (uint32)(((uint64)cSieve->primeFactorBase[i].base*(uint64)cSieve->primeFactorBase[i].twoInverse)%(uint64)p);
		}
	}
	// reset multiplier scan
	cSieve->currentSieveLayerIdx = 0;
	cSieve->currentMultiplierScanIndex = 1;
}
예제 #2
0
void cSieve_prepare(mpz_class& mpzFixedMultiplier, uint32 chainLength, uint32 overwritePrimeFactors=0, uint32 overwriteSieveSize=0)
{
	uint32 sieveSize = (minerSettings.nSieveSize+31)&~31; // align to 32 (4 bytes)
	if( overwriteSieveSize )
		sieveSize = (overwriteSieveSize+31)&~31;
	// todo: Make sure the sieve doesnt crash when the difficulty changes
	if( cSieve == NULL || cSieve->chainLength != chainLength || cSieve->sieveSize != sieveSize || cSieve->nPrimeFactors != minerSettings.nPrimesToSieve )
	{
		if( cSieve == NULL )
		{
			cSieve = (continuousSieve_t*)malloc(sizeof(continuousSieve_t));
			memset(cSieve, 0x00, sizeof(continuousSieve_t));
		}
		// start setting up sieve properties early (to avoid threading issues)
		cSieve->sieveSize = sieveSize;
		cSieve->chainLength = chainLength;
		if( cSieve->sieveSize & 7 )
			__debugbreak(); // must not happen
		cSieve->maskBytes = cSieve->sieveSize/8;
		if( overwritePrimeFactors == 0 )
			cSieve->nPrimeFactors = minerSettings.nPrimesToSieve;
		else
			cSieve->nPrimeFactors = overwritePrimeFactors;
		// free everything that has been allocated before
		if( cSieve->layerMaskC1 )
		{
			free(cSieve->layerMaskC1);
			free(cSieve->layerMaskC2);
			cSieve->layerMaskC1 = NULL;
			cSieve->layerMaskC2 = NULL;
		}
		if( cSieve->primeFactorBase )
		{
			free(cSieve->primeFactorBase);
			cSieve->primeFactorBase = NULL;
		}
		// alloc sieve mask
		uint32 chainMaskSize = cSieve->maskBytes * chainLength;
		if( cSieve->layerMaskC1 == NULL )
		{
			cSieve->layerMaskC1 = (uint8*)malloc(chainMaskSize);
			cSieve->layerMaskC2 = (uint8*)malloc(chainMaskSize);
		}
		// alloc prime factor base table
		if( cSieve->primeFactorBase == NULL )
		{
			cSieve->primeFactorBase = (cPrimeFactor_t*)malloc(sizeof(cPrimeFactor_t)*cSieve->nPrimeFactors);
			for(uint32 i=0; i<cSieve->nPrimeFactors; i++)
			{
				cSieve->primeFactorBase[i].twoInverse = single_modinv(2, vPrimes[i]);
			}
		}
	}
	// calculate fixed inverse
	mpz_class mpzF, mpzTemp;
	for(uint32 i=0; i<cSieve->nPrimeFactors; i++)
	{
		uint32 p = vPrimes[i];
		uint32 fixedFactorMod = mpz_mod_ui(mpzTemp.get_mpz_t(), mpzFixedMultiplier.get_mpz_t(), p);
		cSieve->primeFactorBase[i].mod = fixedFactorMod; 
		cSieve->primeFactorBase[i].base = single_modinv(fixedFactorMod, p); 
	}
	// reset sieve
	memset(cSieve->layerMaskC1, 0x00, cSieve->maskBytes * chainLength);
	memset(cSieve->layerMaskC2, 0x00, cSieve->maskBytes * chainLength);
	cSieve->mpzFixedMultiplier = mpzFixedMultiplier;
	for(uint32 t=0; t<cSieve->chainLength; t++)
	{
		mpzF = mpzFixedMultiplier;
		uint8* maskC1 = cSieve->layerMaskC1+t*cSieve->maskBytes; 
		uint8* maskC2 = cSieve->layerMaskC2+t*cSieve->maskBytes; 
		for(uint32 i=0; i<cSieve->nPrimeFactors; i++)
		{
			if( cSieve->primeFactorBase[i].mod == 0 )
				continue;
			uint32 p = vPrimes[i];
			/*uint32 fixedFactorMod = mpz_mod_ui(mpzTemp.get_mpz_t(), mpzF.get_mpz_t(), p);
			uint32 fixedInverseU32 = single_modinv(fixedFactorMod, p); 
			*///uint32 fixedInverseTwo = single_modinv(2, p);
			
			// mark all cunningham chains of first kind
			uint32 nSolvedMultiplier = cSieve->primeFactorBase[i].base;
			while( nSolvedMultiplier < cSieve->sieveSize )
			{
				maskC1[nSolvedMultiplier>>3] |= (1<<(nSolvedMultiplier&7));
				nSolvedMultiplier += p;
			}
			// mark all cunningham chains of second kind
			nSolvedMultiplier = -cSieve->primeFactorBase[i].base + p; // tested and correct
			nSolvedMultiplier %= (uint64)p;
			while( nSolvedMultiplier < cSieve->sieveSize )
			{
				maskC2[nSolvedMultiplier>>3] |= (1<<(nSolvedMultiplier&7));			
				nSolvedMultiplier += p;
			}
			// apply *2 factor to prime base
			//cSieve->primeFactorBase[i].base = (cSieve->primeFactorBase[i].base*cSieve->primeFactorBase[i].twoInverse)%p;
			cSieve->primeFactorBase[i].base = (uint32)(((uint64)cSieve->primeFactorBase[i].base*(uint64)cSieve->primeFactorBase[i].twoInverse)%(uint64)p);
		}
	}
	// reset multiplier scan
	cSieve->currentSieveLayerIdx = 0;
	cSieve->currentMultiplierScanIndex = 1;
}