Skip to content

Commit

Permalink
Updated to copy sieves between threads and combine them afterwards.
Browse files Browse the repository at this point in the history
  • Loading branch information
tfpf committed Apr 30, 2024
1 parent 91f0705 commit 39dc4f5
Showing 1 changed file with 27 additions and 30 deletions.
57 changes: 27 additions & 30 deletions src/utils/objects/sieve_of_atkin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,35 +46,32 @@ impl SieveOfAtkin {
sieve_of_atkin
}
fn init(&mut self) {
let (tx, rx) = std::sync::mpsc::channel();
let mut sieve3 = self.sieve.clone();
let mut sieve2 = self.sieve.clone();
let sieve1 = self.sieve.as_mut_slice();
std::thread::scope(|s| {
let (tx1, tx2, tx3) = (tx.clone(), tx.clone(), tx.clone());
let sieve_len = self.sieve.len() as i64;
s.spawn(move || {
s.spawn(|| {
for delta in [1, 13, 17, 29, 37, 41, 49, 53] {
SieveOfAtkin::algorithm_3_1(delta, sieve_len, &tx1);
SieveOfAtkin::algorithm_3_1(delta, sieve1);
}
});
s.spawn(move || {
s.spawn(|| {
for delta in [7, 19, 31, 43] {
SieveOfAtkin::algorithm_3_2(delta, sieve_len, &tx2);
SieveOfAtkin::algorithm_3_2(delta, &mut sieve2);
}
});
s.spawn(move || {
s.spawn(|| {
for delta in [11, 23, 47, 59] {
SieveOfAtkin::algorithm_3_3(delta, sieve_len, &tx3);
SieveOfAtkin::algorithm_3_3(delta, &mut sieve3);
}
});
drop(tx);
for (k, delta) in rx {
self.sieve[k as usize] ^= 1u16 << SieveOfAtkin::SHIFTS[delta as usize];
}
});

// 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() {
self.sieve[sieve_idx] ^= sieve2[sieve_idx] ^ sieve3[sieve_idx];
for shift in 0..16 {
if self.sieve[sieve_idx] >> shift & 1 == 1 {
let num_sqr = num.pow(2);
Expand All @@ -92,40 +89,40 @@ impl SieveOfAtkin {
}
}
}
fn algorithm_3_1(delta: i32, sieve_len: i64, tx: &std::sync::mpsc::Sender<(i64, i32)>) {
fn algorithm_3_1(delta: i32, sieve: &mut [u16]) {
for f in 1..=15 {
for g in (1..=30).step_by(2) {
let quadratic = 4 * f * f + g * g;
if delta == quadratic % 60 {
SieveOfAtkin::algorithm_4_1(delta, f, g, quadratic / 60, sieve_len, tx);
SieveOfAtkin::algorithm_4_1(delta, f, g, quadratic / 60, sieve);
}
}
}
}
fn algorithm_3_2(delta: i32, sieve_len: i64, tx: &std::sync::mpsc::Sender<(i64, i32)>) {
fn algorithm_3_2(delta: i32, sieve: &mut [u16]) {
for f in (1..=10).step_by(2) {
for g in [2, 4, 8, 10, 14, 16, 20, 22, 26, 28] {
let quadratic = 3 * f * f + g * g;
if delta == quadratic % 60 {
SieveOfAtkin::algorithm_4_2(delta, f, g, quadratic / 60, sieve_len, tx);
SieveOfAtkin::algorithm_4_2(delta, f, g, quadratic / 60, sieve);
}
}
}
}
fn algorithm_3_3(delta: i32, sieve_len: i64, tx: &std::sync::mpsc::Sender<(i64, i32)>) {
fn algorithm_3_3(delta: i32, sieve: &mut [u16]) {
for (f, gstart) in (1..=10).zip([2, 1].into_iter().cycle()) {
for g in (gstart..=30).step_by(2) {
let quadratic = 3i32 * f * f - g * g;
// Remainder can be negative, so perform modulo operation.
if delta == quadratic.rem_euclid(60) {
SieveOfAtkin::algorithm_4_3(delta, f, g, quadratic.div_euclid(60), sieve_len, tx);
SieveOfAtkin::algorithm_4_3(delta, f, g, quadratic.div_euclid(60), sieve);
}
}
}
}
fn algorithm_4_1(delta: i32, f: i32, g: i32, h: i32, sieve_len: i64, tx: &std::sync::mpsc::Sender<(i64, i32)>) {
fn algorithm_4_1(delta: i32, f: i32, g: i32, h: i32, sieve: &mut [u16]) {
let (mut x, mut y0, mut k0) = (f as i64, g as i64, h as i64);
while k0 < sieve_len {
while k0 < sieve.len() as i64 {
(k0, x) = (k0 + 2 * x + 15, x + 15);
}
loop {
Expand All @@ -137,15 +134,15 @@ impl SieveOfAtkin {
(k0, y0) = (k0 + y0 + 15, y0 + 30);
}
let (mut k, mut y) = (k0, y0);
while k < sieve_len {
tx.send((k, delta)).unwrap();
while k < sieve.len() as i64 {
sieve[k as usize] ^= 1u16 << SieveOfAtkin::SHIFTS[delta as usize];
(k, y) = (k + y + 15, y + 30);
}
}
}
fn algorithm_4_2(delta: i32, f: i32, g: i32, h: i32, sieve_len: i64, tx: &std::sync::mpsc::Sender<(i64, i32)>) {
fn algorithm_4_2(delta: i32, f: i32, g: i32, h: i32, sieve: &mut [u16]) {
let (mut x, mut y0, mut k0) = (f as i64, g as i64, h as i64);
while k0 < sieve_len {
while k0 < sieve.len() as i64 {
(k0, x) = (k0 + x + 5, x + 10);
}
loop {
Expand All @@ -157,24 +154,24 @@ impl SieveOfAtkin {
(k0, y0) = (k0 + y0 + 15, y0 + 30);
}
let (mut k, mut y) = (k0, y0);
while k < sieve_len {
tx.send((k, delta)).unwrap();
while k < sieve.len() as i64 {
sieve[k as usize] ^= 1u16 << SieveOfAtkin::SHIFTS[delta as usize];
(k, y) = (k + y + 15, y + 30);
}
}
}
fn algorithm_4_3(delta: i32, f: i32, g: i32, h: i32, sieve_len: i64, tx: &std::sync::mpsc::Sender<(i64, i32)>) {
fn algorithm_4_3(delta: i32, f: i32, g: i32, h: i32, sieve: &mut [u16]) {
let (mut x, mut y0, mut k0) = (f as i64, g as i64, h as i64);
loop {
while k0 >= sieve_len {
while k0 >= sieve.len() as i64 {
if x <= y0 {
return;
}
(k0, y0) = (k0 - y0 - 15, y0 + 30);
}
let (mut k, mut y) = (k0, y0);
while k >= 0 && y < x {
tx.send((k, delta)).unwrap();
sieve[k as usize] ^= 1u16 << SieveOfAtkin::SHIFTS[delta as usize];
(k, y) = (k - y - 15, y + 30);
}
(k0, x) = (k0 + x + 5, x + 10);
Expand Down

0 comments on commit 39dc4f5

Please sign in to comment.