Skip to content
Permalink
Browse files

Refactor

  • Loading branch information
kimwalisch committed Dec 18, 2019
1 parent 5f5d6da commit 68f05b4e5b1b9bb18677aa5d5a93fea3e1bcebca
Showing with 23 additions and 22 deletions.
  1. +7 −8 include/primesieve/Erat.hpp
  2. +7 −7 src/PrimeGenerator.cpp
  3. +7 −5 src/PrintPrimes.cpp
  4. +2 −2 src/SievingPrimes.cpp
@@ -55,7 +55,7 @@ class Erat
void addSievingPrime(uint64_t);
NOINLINE void sieveSegment();
bool hasNextSegment() const;
static uint64_t nextPrime(uint64_t*, uint64_t);
static uint64_t nextPrime(uint64_t, uint64_t);

private:
uint64_t maxPreSieve_ = 0;
@@ -74,22 +74,21 @@ class Erat
void sieveLastSegment();
};

/// Find the first set bit and calculate the
/// corresponding prime, then unset that bit.
/// Find the first set bit and calculate
/// the corresponding prime.
///
inline uint64_t Erat::nextPrime(uint64_t* bits, uint64_t low)
inline uint64_t Erat::nextPrime(uint64_t bits, uint64_t low)
{
// Calculate bitValues[bitScanForward(*bits)] using a custom
// Calculate bitValues[bitScanForward(bits)] using a custom
// De Bruijn bitscan (that directly computes the bitValue
// without ever computing the bitIndex). For primesieve's
// use case this is as fast as the bsf or tzcnt instructions
// on x64 but more portable.
// https://www.chessprogramming.org/BitScan#De_Bruijn_Multiplication
uint64_t debruijn = 0x3F08A4C6ACB9DBDull;
uint64_t mask = *bits - 1;
uint64_t bitValue = bruijnBitValues[((*bits ^ mask) * debruijn) >> 58];
uint64_t hash = ((bits ^ (bits - 1)) * debruijn) >> 58;
uint64_t bitValue = bruijnBitValues[hash];
uint64_t prime = low + bitValue;
*bits &= mask;
return prime;
}

@@ -266,8 +266,8 @@ void PrimeGenerator::fill(vector<uint64_t>& primes)
{
uint64_t bits = littleendian_cast<uint64_t>(&sieve_[sieveIdx_]);

while (bits)
primes.push_back(nextPrime(&bits, low_));
for (; bits != 0; bits &= bits - 1)
primes.push_back(nextPrime(bits, low_));

low_ += 8 * 30;
sieveIdx_ += 8;
@@ -293,7 +293,7 @@ void PrimeGenerator::fill(vector<uint64_t>& primes,

// Use local variables to prevent the compiler from
// writing temporary results to memory.
size_t i = 0;
size_t num = 0;
size_t maxSize = primes.size();
assert(maxSize >= 64);
uint64_t low = low_;
@@ -309,18 +309,18 @@ void PrimeGenerator::fill(vector<uint64_t>& primes,
{
uint64_t bits = littleendian_cast<uint64_t>(&sieve[sieveIdx]);

for (; bits != 0; i++)
primes[i] = nextPrime(&bits, low);
for (; bits != 0; bits &= bits - 1)
primes[num++] = nextPrime(bits, low);

low += 8 * 30;
sieveIdx += 8;
}
while (i <= maxSize - 64 &&
while (num <= maxSize - 64 &&
sieveIdx < sieveSize);

low_ = low;
sieveIdx_ = sieveIdx;
*size = i;
*size = num;
}
while (*size == 0);
}
@@ -158,8 +158,8 @@ void PrintPrimes::printPrimes() const
for (; i < size; i += 8)
{
uint64_t bits = littleendian_cast<uint64_t>(&sieve_[i]);
while (bits)
primes << nextPrime(&bits, low) << '\n';
for (; bits != 0; bits &= bits - 1)
primes << nextPrime(bits, low) << '\n';

low += 8 * 30;
}
@@ -186,10 +186,12 @@ void PrintPrimes::printkTuplets() const
{
kTuplets << "(";
uint64_t bits = *bitmask;
while (bits != 0)

for (; bits != 0; bits &= bits - 1)
{
kTuplets << nextPrime(&bits, low);
kTuplets << ((bits != 0) ? ", " : ")\n");
kTuplets << nextPrime(bits, low);
bool hasNext = (bits & (bits - 1)) != 0;
kTuplets << (hasNext ? ", " : ")\n");
}
}
}
@@ -68,8 +68,8 @@ void SievingPrimes::fill()
{
uint64_t bits = littleendian_cast<uint64_t>(&sieve_[sieveIdx_]);

for (; bits != 0; num++)
primes_[num] = nextPrime(&bits, low_);
for (; bits != 0; bits &= bits - 1)
primes_[num++] = nextPrime(bits, low_);

low_ += 8 * 30;
sieveIdx_ += 8;

0 comments on commit 68f05b4

Please sign in to comment.
You can’t perform that action at this time.