Skip to content

Commit

Permalink
Implementation of review comment. Is slower, so will revert.
Browse files Browse the repository at this point in the history
  • Loading branch information
tfpf committed Apr 30, 2024
1 parent bb315a0 commit eb5de6d
Showing 1 changed file with 12 additions and 17 deletions.
29 changes: 12 additions & 17 deletions src/utils/objects/sieve_of_atkin.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use crate::utils;

/// A. O. L. Atkin and D. J. Bernstein, "Prime Sieves Using Binary Quadratic
/// Forms", in Mathematics of Computation, vol. 73, no. 246, pp. 1023–1030.
/// Generate prime numbers using the sieve of Atkin. This sieves prime numbers
Expand All @@ -10,7 +8,6 @@ use crate::utils;
pub struct SieveOfAtkin {
limit: usize,
limit_rounded: usize,
limit_rounded_isqrt: usize,
sieve: Vec<u16>,
}
impl SieveOfAtkin {
Expand Down Expand Up @@ -39,7 +36,6 @@ impl SieveOfAtkin {
let mut sieve_of_atkin = SieveOfAtkin {
limit,
limit_rounded,
limit_rounded_isqrt: utils::isqrt(limit_rounded as i64) as usize,
sieve: vec![0; limit / 60 + 1],
};
sieve_of_atkin.init();
Expand Down Expand Up @@ -73,32 +69,31 @@ impl SieveOfAtkin {
});
});

// Combine the results. Since no two threads operated on bits at the
// same position, the bitfields can simply be ORed. Zipping them
// instead of their iterators ensures that they get dropped
// automatically.
for (((s0, s1), s2), s3) in sieve0.iter_mut().zip(sieve1).zip(sieve2).zip(sieve3) {
*s0 |= s1 | s2 | s3;
}

// Mark composite all numbers divisible by the squares of primes.
let mut num: usize = 1;
let mut offset = SieveOfAtkin::OFFSETS.iter().cycle();
'sieve: for sieve_idx in 0..self.sieve.len() {
for sieve_idx in 0..self.sieve.len() {
self.sieve[sieve_idx] |= sieve1[sieve_idx] | sieve2[sieve_idx] | sieve3[sieve_idx];
(sieve1[sieve_idx], sieve2[sieve_idx], sieve3[sieve_idx]) = (0, 0, 0);
for shift in 0..16 {
if self.sieve[sieve_idx] >> shift & 1 == 1 {
let num_sqr = num.pow(2);
for multiple in (num_sqr..)
.step_by(num_sqr)
.take_while(|&multiple| multiple < self.limit_rounded)
{
self.sieve[multiple / 60] &= !(1u32 << SieveOfAtkin::SHIFTS[multiple % 60]) as u16;
let (multiple_div_60, multiple_mod_60) = (multiple / 60, multiple % 60);
self.sieve[multiple_div_60] |=
sieve1[multiple_div_60] | sieve2[multiple_div_60] | sieve3[multiple_div_60];
(
sieve1[multiple_div_60],
sieve2[multiple_div_60],
sieve3[multiple_div_60],
) = (0, 0, 0);
self.sieve[multiple_div_60] &= !(1u32 << SieveOfAtkin::SHIFTS[multiple_mod_60]) as u16;
}
}
num += offset.next().unwrap();
if num > self.limit_rounded_isqrt {
break 'sieve;
}
}
}
}
Expand Down

0 comments on commit eb5de6d

Please sign in to comment.