patterncppModerateCanonical
Parallel sieve of Eratosthenes, version 2
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:
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
Here is the sequential version of
```
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);
/
- Compute the prime numbers \$ p \$ such as \$ p
- Initialize a
std::vectorwithtruefor 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
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.