Skip to content

Commit 22dd5d9

Browse files
fix block race inside sieve prime
1 parent 6caae1d commit 22dd5d9

1 file changed

Lines changed: 24 additions & 5 deletions

File tree

discrete/include/prime.hxx

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,31 @@ requires(std::integral<T> || std::floating_point<T> && !std::is_same_v<bool, T>)
6464
inline static int maxThread = std::thread::hardware_concurrency();
6565

6666
void main_sieve(std::vector<uint64_t> &sieve, T limit, int tid) noexcept {
67+
size_t W = sieve.size();
68+
size_t w0 = (W * tid) / maxThread;
69+
size_t w1 = (W * (tid + 1)) / maxThread;
70+
71+
size_t bit0 = w0 * 64;
72+
size_t bit1 = w1 * 64;
73+
6774
for (T p = 3; p * p <= limit; p += 2) {
68-
const size_t i = (p - 3) >> 1;
69-
if (!(sieve[i >> 6] & (1ULL << (i & 63)))) continue;
70-
for (T j = p * p + 2 * p * tid; j <= limit; j += 2 * p * maxThread) {
71-
const size_t idx = (j - 3) >> 1;
72-
sieve[idx >> 6] &= ~(1ULL << (idx & 63));
75+
size_t pi = (p - 3) >> 1;
76+
if (!(sieve[pi >> 6] & (1ULL << (pi & 63))))
77+
continue;
78+
79+
T j = p * p;
80+
size_t ji = (j - 3) >> 1;
81+
82+
if (ji < bit0) {
83+
T step = 2 * p;
84+
T need = bit0 - ji;
85+
T k = (need + step - 1) / step;
86+
j += k * step;
87+
ji = (j - 3) >> 1;
88+
}
89+
90+
for (; ji < bit1; j += 2 * p, ji = (j - 3) >> 1) {
91+
sieve[ji >> 6] &= ~(1ULL << (ji & 63));
7392
}
7493
}
7594
}

0 commit comments

Comments
 (0)