HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppModerateCanonical

Parallel sieve of Eratosthenes, version 2

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
versionparallelsieveeratosthenes

Problem

This question is a revision of Parallel sieve of Eratosthenes. The goal is to implement a sieve of Eratosthenes with parallel strikes out from the boolean array. I tried to fix the data races and all the threading-related errors as well as to add some of the ideas from the previous answers. Now, the implementation works as follows:

  • Compute the prime numbers \$ p \$ such as \$ p



  • Initialize a std::vector with true for indices between \$ 0 \$ and \$ n \$ (inclusive).



  • Compute the number of threads that should be used to concurrently strike out values from the vector. This number depends on the maximum number of concurrent threads allowed by the implementation and on the number of precomputed prime numbers.



  • Spawn threads that will strike out the multiples of a given set of prime numbers from the boolean vector.



  • Join the threads.



  • Find the actual remaining prime numbers.



To differentiate between the sequential and parallel versions of the sieve, I had the function take an execution policy parameter first, inspired from the C++ parallelism TS N3960. The execution policy classes can be trivially implemented as such (I know... we shouldn't add anything new to std::):

namespace std
{
namespace parallel
{
    struct sequential_execution_policy {};
    struct parallel_execution_policy {};
    struct vector_execution_policy {};

    constexpr sequential_execution_policy   seq = sequential_execution_policy();
    constexpr parallel_execution_policy     par = parallel_execution_policy();
    constexpr vector_execution_policy       vec = vector_execution_policy();
}}


Here is the sequential version of sieve_eratosthenes. In the end, I did not make strike_out_multiples a lambda since I use it multiple times.

```
template
void strike_out_multiples(Integer n, std::vector& vec)
{
for (Integer i = n*2u ; i
auto sieve_eratosthenes(std::parallel::sequential_execution_policy, Integer n)
-> std::vector
{
if (n is_prime(n+1u, true);

/

Solution

Equally-sized sequential subsets of primes don't evenly divide the task. The smallest numbers lead to a lot more multiples.

Test-before-set might significantly reduce cache contention. Even better, don't start at prime2u, start at primeprime.

Context

StackExchange Code Review Q#47067, answer score: 11

Revisions (0)

No revisions yet.