Skip to content

Commit

Permalink
Static presieve lookup tables (#152)
Browse files Browse the repository at this point in the history
  • Loading branch information
kimwalisch authored Nov 8, 2024
1 parent 458e3fb commit 3627bd2
Show file tree
Hide file tree
Showing 19 changed files with 10,964 additions and 391 deletions.
6 changes: 4 additions & 2 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
Changes in version 12.6, 05/11/2024
Changes in version 12.6, 08/11/2024
===================================

* CpuInfo.cpp: Correctly detect Intel Arrow Lake CPU cache
topology on Windows and Linux.
topology on Windows and Linux.
* PreSieve.cpp: Use static pre-sieve lookup tables, this avoids
initialization overhead to generate these lookup tables.

Changes in version 12.5, 22/10/2024
===================================
Expand Down
5 changes: 1 addition & 4 deletions include/primesieve/Erat.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@

namespace primesieve {

class PreSieve;
class MemoryPool;

/// The abstract Erat class sieves primes using the segmented sieve
Expand All @@ -49,17 +48,15 @@ class Erat
Vector<uint8_t> sieve_;
Erat() = default;
Erat(uint64_t, uint64_t);
void init(uint64_t, uint64_t, uint64_t, PreSieve&, MemoryPool& memoryPool);
void init(uint64_t, uint64_t, uint64_t, MemoryPool& memoryPool);
void addSievingPrime(uint64_t);
NOINLINE void sieveSegment();
bool hasNextSegment() const;
static uint64_t nextPrime(uint64_t, uint64_t);

private:
uint64_t maxPreSieve_ = 0;
uint64_t maxEratSmall_ = 0;
uint64_t maxEratMedium_ = 0;
PreSieve* preSieve_ = nullptr;
EratSmall eratSmall_;
EratBig eratBig_;
EratMedium eratMedium_;
Expand Down
9 changes: 3 additions & 6 deletions include/primesieve/IteratorHelper.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
///
/// @file IteratorHelper.hpp
///
/// Copyright (C) 2023 Kim Walisch, <[email protected]>
/// Copyright (C) 2024 Kim Walisch, <[email protected]>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
Expand All @@ -11,7 +11,6 @@
#define ITERATOR_HELPER_HPP

#include "PrimeGenerator.hpp"
#include "PreSieve.hpp"
#include "macros.hpp"
#include "Vector.hpp"

Expand Down Expand Up @@ -48,22 +47,20 @@ struct IteratorData
}

void newPrimeGenerator(uint64_t start,
uint64_t stop,
PreSieve& preSieve)
uint64_t stop)
{
// We use placement new to put the PrimeGenerator
// into an existing buffer. This way we don't
// need to allocate any new memory.
ASSERT(primeGenerator == nullptr);
primeGenerator = new (primeGeneratorBuffer) PrimeGenerator(start, stop, preSieve);
primeGenerator = new (primeGeneratorBuffer) PrimeGenerator(start, stop);
}

uint64_t stop;
uint64_t dist = 0;
bool include_start_number = true;
PrimeGenerator* primeGenerator = nullptr;
Vector<uint64_t> primes;
PreSieve preSieve;
alignas(PrimeGenerator) char primeGeneratorBuffer[sizeof(PrimeGenerator)];
};

Expand Down
30 changes: 11 additions & 19 deletions include/primesieve/PreSieve.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,21 @@
/// from them at initialization. Each buffer is assigned
/// different primes, for example:
///
/// Buffer 0 removes multiplies of: { 7, 67, 71 }
/// Buffer 1 removes multiplies of: { 11, 41, 73 }
/// Buffer 2 removes multiplies of: { 13, 43, 59 }
/// Buffer 3 removes multiplies of: { 17, 37, 53 }
/// Buffer 4 removes multiplies of: { 19, 29, 61 }
/// Buffer 5 removes multiplies of: { 23, 31, 47 }
/// Buffer 6 removes multiplies of: { 79, 97 }
/// Buffer 7 removes multiplies of: { 83, 89 }
/// buffer[0] removes multiplies of: { 7, 67, 71 } // 32 KiB
/// buffer[1] removes multiplies of: { 11, 41, 73 } // 32 KiB
/// buffer[2] removes multiplies of: { 13, 43, 59 } // 32 KiB
/// buffer[3] removes multiplies of: { 17, 37, 53 } // 32 KiB
/// buffer[4] removes multiplies of: { 19, 29, 61 } // 32 KiB
/// buffer[5] removes multiplies of: { 23, 31, 47 } // 32 KiB
/// buffer[6] removes multiplies of: { 79, 97 } // 8 KiB
/// buffer[7] removes multiplies of: { 83, 89 } // 7 KiB
///
/// Then whilst sieving, we perform a bitwise AND on the
/// buffers_ arrays and store the result in the sieve array.
/// Pre-sieving provides a speedup of up to 30% when
/// sieving the primes < 10^10 using primesieve.
///
/// Copyright (C) 2023 Kim Walisch, <[email protected]>
/// Copyright (C) 2024 Kim Walisch, <[email protected]>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
Expand All @@ -37,16 +37,8 @@ namespace primesieve {
class PreSieve
{
public:
void init(uint64_t start, uint64_t stop);
void preSieve(Vector<uint8_t>& sieve, uint64_t segmentLow) const;
uint64_t getMaxPrime() const { return maxPrime_; }
private:
uint64_t maxPrime_ = 13;
uint64_t totalDist_ = 0;
Array<Vector<uint8_t>, 8> buffers_;
void initBuffers();
static void preSieveSmall(Vector<uint8_t>& sieve, uint64_t segmentLow);
void preSieveLarge(Vector<uint8_t>& sieve, uint64_t segmentLow) const;
static void preSieve(Vector<uint8_t>& sieve, uint64_t segmentLow);
static uint64_t getMaxPrime() { return 97; }
};

} // namespace
Expand Down
Loading

0 comments on commit 3627bd2

Please sign in to comment.