Compare commits
No commits in common. "multithread" and "main" have entirely different histories.
multithrea
...
main
20
Cargo.lock
generated
20
Cargo.lock
generated
@ -2,24 +2,6 @@
|
|||||||
# 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-multithread"
|
version = "1.0.0"
|
||||||
dependencies = [
|
|
||||||
"itertools",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "itertools"
|
|
||||||
version = "0.13.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
|
|
||||||
dependencies = [
|
|
||||||
"either",
|
|
||||||
]
|
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "hcn"
|
name = "hcn"
|
||||||
version = "1.0.0-multithread"
|
version = "1.0.0"
|
||||||
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,14 +1,7 @@
|
|||||||
mod sieve;
|
mod sieve;
|
||||||
|
|
||||||
use std::{
|
use std::time::Instant;
|
||||||
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;
|
||||||
@ -51,76 +44,21 @@ 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;
|
||||||
|
|
||||||
for (nr, teilers) in results.into_iter().sorted() {
|
let start = Instant::now();
|
||||||
|
|
||||||
|
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}");
|
println!("{nr}: {teilers} ({:?} since start)", start.elapsed());
|
||||||
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