It has already been mentioned in an answeran answer to the previous question, but there are really many places where the code does useless iterations on multiples of 2. Actually, these useless operations can be removed almost everywhere:
- In the sequential version of the sieve,
strike_out_multiples(2u, is_prime);
can be removed since the multiples of 2 are not even considered by the algorithm in the last part of the function where the actual prime numbers are added to the vector. Therefore, we don't needstrike_out_multiples
as a separate function anymore since it's only used once. - Similarly,
first
can be declared asstd::size_t first = 1u
in the parallel version of the algorithm:0u
corresponds to the index of the vector where the prime number2u
is stored. - There are loops that begin with
2u*prime
at several places in the code. It has been proposed in another answeranother answer that these loops should begin atprime*prime
instead, which is always odd since we ignore2u
. Consequently, the increment of these loops can be changed ton += 2u*prime
(instead ofn += prime
) to ignore the even values. - The initialization of
is_prime
in the parallel version of the sieve can begin at the index3u
(the previous ones can be ignored) and have an increment of2u
to skip the even values.
This highlights the fact that the vector is_prime
contains twice as many values as it could contain: the values below 3u
and all the even values are not used. There ought to be a way to avoid uselessly storing that many values.