better multithread
This commit is contained in:
parent
c359ca292a
commit
c607c3949f
56
Cargo.lock
generated
56
Cargo.lock
generated
@ -8,11 +8,33 @@ version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "isprime"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"thread-priority",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.139"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -44,3 +66,37 @@ checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread-priority"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "978519ae4c6891352f964b88da4ab5a3a9b74a40247cda5baee145dae6cd3b71"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"log",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
@ -7,6 +7,7 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
num-bigint = { default-features = false, version = "0.4.3" }
|
||||
thread-priority = "0.10.0"
|
||||
|
||||
[profile.release]
|
||||
lto = true # Enable link-time optimization
|
||||
|
@ -1,21 +1,13 @@
|
||||
|
||||
|
||||
pub mod prime_utils {
|
||||
use num_bigint::BigUint;
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct PrimeUtils {
|
||||
//prime_cache: Vec<BigUint>
|
||||
}
|
||||
|
||||
impl PrimeUtils {
|
||||
|
||||
pub fn new() -> Self {
|
||||
Self { }
|
||||
}
|
||||
|
||||
pub fn log_2(self: &Self, x: BigUint) -> u64 {
|
||||
pub fn log_2(x: BigUint) -> u64 {
|
||||
x.bits() - 1
|
||||
}
|
||||
|
||||
pub fn is_prime(self: &Self, number: &BigUint) -> bool {
|
||||
pub fn is_prime(number: &BigUint, g_primes: &Vec<BigUint>) -> bool {
|
||||
if BigUint::from(1u8) == *number {
|
||||
return false;
|
||||
}
|
||||
@ -31,7 +23,7 @@ impl PrimeUtils {
|
||||
|
||||
// number = 2^a - 1
|
||||
// a = log2(number + 1)
|
||||
let a = self.log_2(number+1u8);
|
||||
let a = log_2(number+1u8);
|
||||
if BigUint::from(2u8).pow(a as u32)-BigUint::from(1u8) != *number {
|
||||
let mut i = BigUint::from(1u8);
|
||||
let one = BigUint::from(1u8);
|
||||
@ -39,6 +31,22 @@ impl PrimeUtils {
|
||||
|
||||
let sqrtnum = number.sqrt()+&one; //fake ceil function
|
||||
let mut is_prime = true;
|
||||
|
||||
match g_primes.iter().max() {
|
||||
Some(max_value) => {
|
||||
if max_value > &sqrtnum {
|
||||
for prime in g_primes {
|
||||
if prime<&sqrtnum {
|
||||
if number%prime == zero {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
None => {}
|
||||
};
|
||||
|
||||
loop {
|
||||
i = i + &one;
|
||||
if number%&i == zero {
|
||||
|
69
src/main.rs
69
src/main.rs
@ -2,7 +2,8 @@ pub mod is_prime;
|
||||
|
||||
use std::{time::SystemTime,thread};
|
||||
use num_bigint::BigUint;
|
||||
use crate::is_prime::PrimeUtils;
|
||||
use crate::is_prime::prime_utils;
|
||||
use thread_priority::{set_current_thread_priority,ThreadPriority};
|
||||
|
||||
fn p(n: f64) -> f64 {
|
||||
let ln_n = n.ln();
|
||||
@ -19,6 +20,9 @@ fn p(n: f64) -> f64 {
|
||||
|
||||
|
||||
fn main() {
|
||||
|
||||
assert!(set_current_thread_priority(ThreadPriority::Max).is_ok());
|
||||
|
||||
/*
|
||||
let mut buffer = String::new();
|
||||
let stdin = io::stdin();
|
||||
@ -38,34 +42,61 @@ fn main() {
|
||||
|
||||
let sys_time = SystemTime::now();
|
||||
|
||||
let utils = PrimeUtils::new();
|
||||
|
||||
let n:f64 = 1_000f64;
|
||||
let nthprime_approx = p(n*1.01) as u128;
|
||||
let n:f64 = 1_000_000f64;
|
||||
let nthprime_approx = p(n*1.02) as u128;
|
||||
const THREADS: u128 = 12;
|
||||
let workloads = nthprime_approx/THREADS;
|
||||
|
||||
let mut primes: Vec<BigUint> = vec![];
|
||||
let primecache: Vec<BigUint> = vec![];
|
||||
let primemutex = std::sync::Mutex::new(primecache);
|
||||
let primearc = std::sync::Arc::new(primemutex);
|
||||
let mut joins = vec![];
|
||||
for i in 0..THREADS {
|
||||
let arcclone = primearc.clone();
|
||||
let tprimes = thread::spawn(move || {
|
||||
let mut lprimes = vec![];
|
||||
|
||||
assert!(set_current_thread_priority(ThreadPriority::Max).is_ok());
|
||||
|
||||
let one_thousand = &BigUint::from(1_000u16);
|
||||
let one_hundred = &BigUint::from(100u8);
|
||||
let ten = &BigUint::from(10u8);
|
||||
|
||||
|
||||
let work_uint = BigUint::from(workloads);
|
||||
let mut number = BigUint::from(i)*&work_uint;
|
||||
let inc = BigUint::from(1u8);
|
||||
// let zero = BigUint::from(0u8);
|
||||
|
||||
let max = BigUint::from(i+1)*work_uint;
|
||||
|
||||
let mut primecache = vec![];
|
||||
loop {
|
||||
number = number + &inc;
|
||||
if utils.is_prime(&number) {
|
||||
lprimes.push(number.clone());
|
||||
|
||||
if prime_utils::is_prime(&number,&mut primecache) {
|
||||
primecache.push(number.clone());
|
||||
//println!("Found a prime {} {}",number, primecache.len());
|
||||
}
|
||||
if (&number * one_thousand)/&max/ten == &number/&max*one_hundred {
|
||||
let mut new_primecache = arcclone.lock().unwrap();
|
||||
new_primecache.append(&mut primecache);
|
||||
new_primecache.sort();
|
||||
new_primecache.dedup();
|
||||
|
||||
primecache = new_primecache.clone();
|
||||
|
||||
}
|
||||
if number == max {
|
||||
break;
|
||||
}
|
||||
}
|
||||
lprimes
|
||||
|
||||
let mut new_primecache = arcclone.lock().unwrap();
|
||||
new_primecache.append(&mut primecache);
|
||||
drop(primecache);
|
||||
new_primecache.sort();
|
||||
new_primecache.dedup();
|
||||
|
||||
true
|
||||
});
|
||||
joins.push(tprimes);
|
||||
}
|
||||
@ -74,10 +105,7 @@ fn main() {
|
||||
let mut njoins = vec![];
|
||||
for join in joins {
|
||||
if join.is_finished() {
|
||||
let tp = join.join();
|
||||
if let Ok(mut tprimes) = tp {
|
||||
primes.append(&mut tprimes);
|
||||
}
|
||||
join.join().unwrap();
|
||||
} else {
|
||||
njoins.push(join);
|
||||
}
|
||||
@ -87,20 +115,25 @@ fn main() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
let mut primes = primearc.lock().unwrap().to_vec();
|
||||
|
||||
let removed = (primes.len()-n as usize).clamp(0, primes.len());
|
||||
if removed != 0 {
|
||||
println!("removing {removed} primes");
|
||||
for _ in 0..removed {
|
||||
primes.pop();
|
||||
}
|
||||
}
|
||||
|
||||
let added = (n as usize-primes.len()).clamp(0, n as usize);
|
||||
let added = n as usize-primes.len();
|
||||
if primes.len() < n as usize {
|
||||
println!("Less primes than expected!");
|
||||
let mut number = BigUint::from(THREADS)*BigUint::from(workloads);
|
||||
let inc = BigUint::from(1u8);
|
||||
loop {
|
||||
number = number + &inc;
|
||||
if utils.is_prime(&number) {
|
||||
if prime_utils::is_prime(&number, &primes) {
|
||||
primes.push(number.clone());
|
||||
}
|
||||
if primes.len() == n as usize {
|
||||
@ -115,7 +148,7 @@ fn main() {
|
||||
|
||||
println!("{:?}", primes);
|
||||
|
||||
println!("prime count: {}, expected: {}, primes added: {} | {}%",primes.len(),n,added,(added as f64)/primes.len() as f64*100.0);
|
||||
println!("prime count: {}, expected: {}, primes added: {} | {}%, removed: {}",primes.len(),n,added,(added as f64)/primes.len() as f64*100.0, removed);
|
||||
println!("last prime approx: {}",nthprime_approx);
|
||||
|
||||
println!("And that's time: {difference:?}");
|
||||
|
Loading…
x
Reference in New Issue
Block a user