Compare commits
	
		
			4 Commits
		
	
	
		
			main
			...
			multithrea
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| dc82024ed0 | |||
| fd36faae13 | |||
| 490c53a280 | |||
| 939e239b36 | 
							
								
								
									
										22
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										22
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							| @@ -1,7 +1,25 @@ | |||||||
| # This file is automatically @generated by Cargo. | # This file is automatically @generated by Cargo. | ||||||
| # It is not intended for manual editing. | # It is not intended for manual editing. | ||||||
| version = 3 | version = 4 | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "either" | ||||||
|  | version = "1.15.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" | ||||||
|  |  | ||||||
| [[package]] | [[package]] | ||||||
| name = "hcn" | name = "hcn" | ||||||
| version = "1.0.0" | version = "1.0.0-multithread" | ||||||
|  | dependencies = [ | ||||||
|  |  "itertools", | ||||||
|  | ] | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "itertools" | ||||||
|  | version = "0.14.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" | ||||||
|  | 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.14" | ||||||
|  |  | ||||||
| [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); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user