This commit is contained in:
Mystikfluu 2023-03-02 20:53:13 +01:00
parent 5950d10d98
commit 0dd7ea4e7c
4 changed files with 76 additions and 72 deletions

3
.gitignore vendored
View File

@ -1,2 +1,3 @@
/target /target
report.json report.json
primes.json

View File

@ -6,11 +6,11 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
num-bigint = { default-features = false, version = "0.4.3" } num-bigint = { default-features = false, version = "0" }
thread-priority = "0.10.0" thread-priority = "0"
[profile.release] [profile.release]
lto = true # Enable link-time optimization lto = true # Enable link-time optimization
codegen-units = 1 # Reduce number of codegen units to increase optimizations codegen-units = 1 # Reduce number of codegen units to increase optimizations
panic = 'abort' # Abort on panic panic = 'abort' # Abort on panic
# strip = true # Strip symbols from binary; remove pdb strip = true # Strip symbols from binary; remove pdb

View File

@ -30,34 +30,26 @@ pub mod prime_utils {
let zero = BigUint::from(0u8); let zero = BigUint::from(0u8);
let sqrtnum = number.sqrt()+&one; //fake ceil function let sqrtnum = number.sqrt()+&one; //fake ceil function
let mut is_prime = true;
match g_primes.iter().max() { if let Some(max_value) = g_primes.iter().max() {
Some(max_value) => { if max_value > &sqrtnum {
if max_value > &sqrtnum { for prime in g_primes {
for prime in g_primes { if prime<&sqrtnum && number%prime == zero {
if prime<&sqrtnum { return false;
if number%prime == zero {
return false;
}
}
} }
} }
}, }
None => {} }
};
loop {
loop { i += &one;
i = i + &one; if number%&i == zero {
if number%&i == zero { return false;
is_prime = false; }
break; if i == sqrtnum {
} return true;
if i == sqrtnum {
break;
} }
} }
return is_prime;
} }
// 4 12 194 // 4 12 194
@ -66,11 +58,8 @@ pub mod prime_utils {
for _i in 2..a { for _i in 2..a {
last = (last.pow(2)-&two)%number; last = (last.pow(2)-&two)%number;
} }
if last == BigUint::from(0u8) {
true last == BigUint::from(0u8)
} else {
false
}
} }
} }

View File

@ -1,6 +1,8 @@
#![warn(clippy::pedantic)]
pub mod is_prime; pub mod is_prime;
use std::{time::SystemTime,thread}; use std::{time::SystemTime,thread, io::Write};
use num_bigint::BigUint; use num_bigint::BigUint;
use crate::is_prime::prime_utils; use crate::is_prime::prime_utils;
use thread_priority::{set_current_thread_priority,ThreadPriority}; use thread_priority::{set_current_thread_priority,ThreadPriority};
@ -44,9 +46,11 @@ fn main() {
let sys_time = SystemTime::now(); let sys_time = SystemTime::now();
let n:f64 = 1_000_000f64; const N:i64 = 100_000;
let nthprime_approx = p(n*1.02) as u128; const NU:usize = N as usize;
const THREADS: u128 = 12; let nf:f64 = 100_000f64;
let nthprime_approx:usize = p(nf*1.02).ceil() as usize;
const THREADS: usize = 12;
let workloads = nthprime_approx/THREADS; let workloads = nthprime_approx/THREADS;
let primecache: Vec<BigUint> = vec![]; let primecache: Vec<BigUint> = vec![];
@ -55,14 +59,15 @@ fn main() {
let mut joins = vec![]; let mut joins = vec![];
for i in 0..THREADS { for i in 0..THREADS {
let arcclone = primearc.clone(); let arcclone = primearc.clone();
let tprimes = thread::spawn(move || { let handle = thread::spawn(move || {
if set_current_thread_priority(ThreadPriority::Max).is_err() { if set_current_thread_priority(ThreadPriority::Max).is_err() {
eprintln!("failed to set thread priority to max"); eprintln!("failed to set thread priority to max");
} }
let one_thousand = &BigUint::from(1_000u16); const SPLITTER: u128 = 10000u128;
let one_hundred = &BigUint::from(100u8); let one_thousand = &BigUint::from(SPLITTER*10);
let one_hundred = &BigUint::from(SPLITTER);
let ten = &BigUint::from(10u8); let ten = &BigUint::from(10u8);
@ -74,14 +79,18 @@ fn main() {
let max = BigUint::from(i+1)*work_uint; let max = BigUint::from(i+1)*work_uint;
let mut primecache = vec![]; let mut primecache = vec![];
loop { loop {
number = number + &inc; number += &inc;
if prime_utils::is_prime(&number,&mut primecache) { if prime_utils::is_prime(&number,&primecache) {
primecache.push(number.clone()); primecache.push(number.clone());
//println!("Found a prime {} {}",number, primecache.len()); //println!("Found a prime {} {}",number, primecache.len());
} }
if (&number * one_thousand)/&max/ten == &number/&max*one_hundred { if (&number * one_thousand)/&max/ten == &number/&max*one_hundred {
let tried_getting = SystemTime::now();
let mut new_primecache = arcclone.lock().unwrap(); let mut new_primecache = arcclone.lock().unwrap();
if SystemTime::now().duration_since(tried_getting).unwrap().as_millis() > 50 {
eprintln!("Waited 0.05+ seconds for lock!");
}
new_primecache.append(&mut primecache); new_primecache.append(&mut primecache);
new_primecache.sort(); new_primecache.sort();
new_primecache.dedup(); new_primecache.dedup();
@ -96,51 +105,43 @@ fn main() {
let mut new_primecache = arcclone.lock().unwrap(); let mut new_primecache = arcclone.lock().unwrap();
new_primecache.append(&mut primecache); new_primecache.append(&mut primecache);
drop(primecache);
new_primecache.sort(); new_primecache.sort();
new_primecache.dedup(); new_primecache.dedup();
true
}); });
joins.push(tprimes); joins.push(handle);
} }
loop { for handle in joins {
let mut njoins = vec![]; handle.join().unwrap();
for join in joins {
if join.is_finished() {
join.join().unwrap();
} else {
njoins.push(join);
}
}
joins = njoins;
if joins.len()==0 {
break;
}
} }
let mut primes = primearc.lock().unwrap().to_vec(); let mut primes = primearc.lock().unwrap().to_vec();
let removed = (primes.len()-n as usize).clamp(0, primes.len()); let removed:i32 = if primes.len() > NU {
if removed != 0 { let mut rem = 0;
println!("removing {removed} primes"); loop {
for _ in 0..removed { if primes.len() <= NU {
break;
}
rem+=1;
primes.pop(); primes.pop();
} }
} rem
} else {
0
};
let added = n as usize-primes.len(); let added = NU-primes.len();
if primes.len() < n as usize { if primes.len() < NU {
println!("Less primes than expected!"); 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 += &inc;
if prime_utils::is_prime(&number, &primes) { if prime_utils::is_prime(&number, &primes) {
primes.push(number.clone()); primes.push(number.clone());
} }
if primes.len() == n as usize { if primes.len() == NU {
break; break;
} }
} }
@ -150,12 +151,25 @@ fn main() {
let difference = new_sys_time.duration_since(sys_time) let difference = new_sys_time.duration_since(sys_time)
.expect("Clock may have gone backwards"); .expect("Clock may have gone backwards");
println!("{:?}", primes); assert_eq!(primes.len(),NU);
println!("prime count: {}, expected: {}, primes added: {} | {}%, removed: {}",primes.len(),n,added,(added as f64)/primes.len() as f64*100.0, removed); println!("primes added: {} | % added: {}% | removed: {}",added,(added as f64)/primes.len() as f64*100.0,removed);
println!("last prime approx: {}",nthprime_approx);
println!("time: {difference:?}");
println!("writing primes...");
let mut file = std::fs::File::create("primes.json").unwrap();
file.write_all(b"[").unwrap();
let mut it = primes.iter().peekable();
while let Some(prime) = it.next() {
file.write_all(prime.to_string().as_bytes()).unwrap();
if it.peek().is_some() {
file.write_all(b",").unwrap();
}
}
file.write_all(b"]").unwrap();
println!("And that's time: {difference:?}");
} }