Compare commits
3 Commits
main
...
multithrea
Author | SHA1 | Date | |
---|---|---|---|
fd36faae13 | |||
490c53a280 | |||
939e239b36 |
20
Cargo.lock
generated
20
Cargo.lock
generated
@ -2,6 +2,24 @@
|
|||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "either"
|
||||||
|
version = "1.13.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hcn"
|
name = "hcn"
|
||||||
version = "1.0.0"
|
version = "1.0.0-multithread"
|
||||||
|
dependencies = [
|
||||||
|
"itertools",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itertools"
|
||||||
|
version = "0.13.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
|
||||||
|
dependencies = [
|
||||||
|
"either",
|
||||||
|
]
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "hcn"
|
name = "hcn"
|
||||||
version = "1.0.0"
|
version = "1.0.0-multithread"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
itertools = "0.13"
|
||||||
|
|
||||||
[lints.rust]
|
[lints.rust]
|
||||||
unsafe_code = "forbid"
|
unsafe_code = "forbid"
|
||||||
|
74
src/main.rs
74
src/main.rs
@ -1,7 +1,14 @@
|
|||||||
mod sieve;
|
mod sieve;
|
||||||
|
|
||||||
use std::time::Instant;
|
use std::{
|
||||||
|
collections::HashMap,
|
||||||
|
env,
|
||||||
|
sync::Arc,
|
||||||
|
thread::{self, available_parallelism},
|
||||||
|
time::Instant,
|
||||||
|
};
|
||||||
|
|
||||||
|
use itertools::Itertools as _;
|
||||||
use sieve::get_primes;
|
use sieve::get_primes;
|
||||||
|
|
||||||
const MAX_SIEVED_PRIMES: usize = 100_000_000;
|
const MAX_SIEVED_PRIMES: usize = 100_000_000;
|
||||||
@ -44,21 +51,76 @@ fn prime_factors(nr: u64, primes: &[u64]) -> u64 {
|
|||||||
num_teilers
|
num_teilers
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn the_thread(mut start: u64, end: u64, primes: &[u64]) -> HashMap<u64, u64> {
|
||||||
|
let mut max_teilers = 0;
|
||||||
|
let mut max_teilers_hashmap = HashMap::new();
|
||||||
|
|
||||||
|
let mut step_size = 10;
|
||||||
|
|
||||||
|
if start == 0 {
|
||||||
|
start = 2;
|
||||||
|
step_size = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
for nr in (start..=end).step_by(step_size) {
|
||||||
|
let teilers = prime_factors(nr, primes);
|
||||||
|
if teilers > max_teilers {
|
||||||
|
max_teilers = teilers;
|
||||||
|
max_teilers_hashmap.insert(nr, teilers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
max_teilers_hashmap
|
||||||
|
}
|
||||||
|
|
||||||
|
fn calculate_chunk_bounds(i: usize, num_threads: usize, max_nr: usize) -> (usize, usize) {
|
||||||
|
let chunk_size = max_nr / num_threads;
|
||||||
|
let start = i * chunk_size;
|
||||||
|
let end = ((i + 1) * chunk_size).min(max_nr);
|
||||||
|
(start, end)
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
let max_nr = env::args()
|
||||||
|
.nth(1)
|
||||||
|
.expect("Usage: hcn <max_nr>")
|
||||||
|
.parse::<usize>()
|
||||||
|
.expect("Invalid max_nr");
|
||||||
|
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
println!("Precalculating primes...");
|
println!("Precalculating primes...");
|
||||||
let primes = get_primes(MAX_SIEVED_PRIMES);
|
let primes = get_primes(MAX_SIEVED_PRIMES);
|
||||||
println!("{} primes. Took {:?}", primes.len(), start.elapsed());
|
println!("{} primes. Took {:?}", primes.len(), start.elapsed());
|
||||||
|
|
||||||
|
let primes = Arc::new(primes);
|
||||||
|
|
||||||
|
#[allow(clippy::unwrap_used)]
|
||||||
|
let num_threads = available_parallelism().unwrap().get();
|
||||||
|
let mut threads = Vec::with_capacity(num_threads);
|
||||||
|
|
||||||
|
let now = Instant::now();
|
||||||
|
for i in 0..num_threads {
|
||||||
|
let (start, end) = calculate_chunk_bounds(i, num_threads, max_nr);
|
||||||
|
let primes = primes.clone();
|
||||||
|
threads.push(thread::spawn(move || {
|
||||||
|
the_thread(start as u64, end as u64, &primes)
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut results = HashMap::new();
|
||||||
|
for thread in threads {
|
||||||
|
let thread_result = thread.join().expect("Thread failed to join (panicked?)");
|
||||||
|
results.extend(thread_result);
|
||||||
|
}
|
||||||
|
|
||||||
let mut max_teilers = 0;
|
let mut max_teilers = 0;
|
||||||
|
|
||||||
let start = Instant::now();
|
for (nr, teilers) in results.into_iter().sorted() {
|
||||||
|
|
||||||
for nr in (2..1_000_000_000).step_by(2) {
|
|
||||||
let teilers = prime_factors(nr, &primes);
|
|
||||||
if teilers > max_teilers {
|
if teilers > max_teilers {
|
||||||
println!("{nr}: {teilers} ({:?} since start)", start.elapsed());
|
println!("{nr}: {teilers}");
|
||||||
max_teilers = teilers;
|
max_teilers = teilers;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
println!("Took {:?}", now.elapsed());
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ fn find_next_prime(nr: &mut u64, sieve: &mut [bool]) -> Option<u64> {
|
|||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.skip(start_idx)
|
.skip(start_idx)
|
||||||
.find(|&(_, &is_prime)| is_prime)
|
.find(|(_, &is_prime)| is_prime)
|
||||||
{
|
{
|
||||||
*nr = idx as u64;
|
*nr = idx as u64;
|
||||||
return Some(*nr);
|
return Some(*nr);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user