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"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "isprime"
|
name = "isprime"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"num-bigint",
|
"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]]
|
[[package]]
|
||||||
@ -44,3 +66,37 @@ checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"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]
|
[dependencies]
|
||||||
num-bigint = { default-features = false, version = "0.4.3" }
|
num-bigint = { default-features = false, version = "0.4.3" }
|
||||||
|
thread-priority = "0.10.0"
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
lto = true # Enable link-time optimization
|
lto = true # Enable link-time optimization
|
||||||
|
@ -1,21 +1,13 @@
|
|||||||
|
|
||||||
|
|
||||||
|
pub mod prime_utils {
|
||||||
use num_bigint::BigUint;
|
use num_bigint::BigUint;
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
pub fn log_2(x: BigUint) -> u64 {
|
||||||
pub struct PrimeUtils {
|
|
||||||
//prime_cache: Vec<BigUint>
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PrimeUtils {
|
|
||||||
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self { }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn log_2(self: &Self, x: BigUint) -> u64 {
|
|
||||||
x.bits() - 1
|
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 {
|
if BigUint::from(1u8) == *number {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -31,7 +23,7 @@ impl PrimeUtils {
|
|||||||
|
|
||||||
// number = 2^a - 1
|
// number = 2^a - 1
|
||||||
// a = log2(number + 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 {
|
if BigUint::from(2u8).pow(a as u32)-BigUint::from(1u8) != *number {
|
||||||
let mut i = BigUint::from(1u8);
|
let mut i = BigUint::from(1u8);
|
||||||
let one = BigUint::from(1u8);
|
let one = BigUint::from(1u8);
|
||||||
@ -39,6 +31,22 @@ impl PrimeUtils {
|
|||||||
|
|
||||||
let sqrtnum = number.sqrt()+&one; //fake ceil function
|
let sqrtnum = number.sqrt()+&one; //fake ceil function
|
||||||
let mut is_prime = true;
|
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 {
|
loop {
|
||||||
i = i + &one;
|
i = i + &one;
|
||||||
if number%&i == zero {
|
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 std::{time::SystemTime,thread};
|
||||||
use num_bigint::BigUint;
|
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 {
|
fn p(n: f64) -> f64 {
|
||||||
let ln_n = n.ln();
|
let ln_n = n.ln();
|
||||||
@ -19,6 +20,9 @@ fn p(n: f64) -> f64 {
|
|||||||
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
||||||
|
assert!(set_current_thread_priority(ThreadPriority::Max).is_ok());
|
||||||
|
|
||||||
/*
|
/*
|
||||||
let mut buffer = String::new();
|
let mut buffer = String::new();
|
||||||
let stdin = io::stdin();
|
let stdin = io::stdin();
|
||||||
@ -38,34 +42,61 @@ fn main() {
|
|||||||
|
|
||||||
let sys_time = SystemTime::now();
|
let sys_time = SystemTime::now();
|
||||||
|
|
||||||
let utils = PrimeUtils::new();
|
let n:f64 = 1_000_000f64;
|
||||||
|
let nthprime_approx = p(n*1.02) as u128;
|
||||||
let n:f64 = 1_000f64;
|
|
||||||
let nthprime_approx = p(n*1.01) as u128;
|
|
||||||
const THREADS: u128 = 12;
|
const THREADS: u128 = 12;
|
||||||
let workloads = nthprime_approx/THREADS;
|
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![];
|
let mut joins = vec![];
|
||||||
for i in 0..THREADS {
|
for i in 0..THREADS {
|
||||||
|
let arcclone = primearc.clone();
|
||||||
let tprimes = thread::spawn(move || {
|
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 work_uint = BigUint::from(workloads);
|
||||||
let mut number = BigUint::from(i)*&work_uint;
|
let mut number = BigUint::from(i)*&work_uint;
|
||||||
let inc = BigUint::from(1u8);
|
let inc = BigUint::from(1u8);
|
||||||
|
// let zero = BigUint::from(0u8);
|
||||||
|
|
||||||
let max = BigUint::from(i+1)*work_uint;
|
let max = BigUint::from(i+1)*work_uint;
|
||||||
|
let mut primecache = vec![];
|
||||||
loop {
|
loop {
|
||||||
number = number + &inc;
|
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 {
|
if number == max {
|
||||||
break;
|
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);
|
joins.push(tprimes);
|
||||||
}
|
}
|
||||||
@ -74,10 +105,7 @@ fn main() {
|
|||||||
let mut njoins = vec![];
|
let mut njoins = vec![];
|
||||||
for join in joins {
|
for join in joins {
|
||||||
if join.is_finished() {
|
if join.is_finished() {
|
||||||
let tp = join.join();
|
join.join().unwrap();
|
||||||
if let Ok(mut tprimes) = tp {
|
|
||||||
primes.append(&mut tprimes);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
njoins.push(join);
|
njoins.push(join);
|
||||||
}
|
}
|
||||||
@ -87,20 +115,25 @@ fn main() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut primes = primearc.lock().unwrap().to_vec();
|
||||||
|
|
||||||
let removed = (primes.len()-n as usize).clamp(0, primes.len());
|
let removed = (primes.len()-n as usize).clamp(0, primes.len());
|
||||||
if removed != 0 {
|
if removed != 0 {
|
||||||
|
println!("removing {removed} primes");
|
||||||
for _ in 0..removed {
|
for _ in 0..removed {
|
||||||
primes.pop();
|
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 {
|
if primes.len() < n as usize {
|
||||||
|
println!("Less primes than expected!");
|
||||||
let mut number = BigUint::from(THREADS)*BigUint::from(workloads);
|
let mut number = BigUint::from(THREADS)*BigUint::from(workloads);
|
||||||
let inc = BigUint::from(1u8);
|
let inc = BigUint::from(1u8);
|
||||||
loop {
|
loop {
|
||||||
number = number + &inc;
|
number = number + &inc;
|
||||||
if utils.is_prime(&number) {
|
if prime_utils::is_prime(&number, &primes) {
|
||||||
primes.push(number.clone());
|
primes.push(number.clone());
|
||||||
}
|
}
|
||||||
if primes.len() == n as usize {
|
if primes.len() == n as usize {
|
||||||
@ -115,7 +148,7 @@ fn main() {
|
|||||||
|
|
||||||
println!("{:?}", primes);
|
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!("last prime approx: {}",nthprime_approx);
|
||||||
|
|
||||||
println!("And that's time: {difference:?}");
|
println!("And that's time: {difference:?}");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user