Change algorithm to use cached values only

Signed-off-by: trivernis <trivernis@protonmail.com>
pull/1/head
trivernis 4 years ago
parent 1014369493
commit 3f381e3c0c
Signed by: Trivernis
GPG Key ID: DFFFCC2C7A02DB45

@ -5,40 +5,41 @@
*/ */
__kernel void check_prime(const uint LOWER_PRIME_COUNT, __global const ulong *LOWER_PRIMES, __global const ulong *IN, __global bool *OUT) { __kernel void check_prime_cached(const uint LOWER_PRIME_COUNT, __global const ulong *LOWER_PRIMES, __global const ulong *IN, __global bool *OUT) {
uint id = get_global_id(0); uint id = get_global_id(0);
ulong num = IN[id]; ulong num = IN[id];
bool prime = true;
ulong limit = (ulong) native_sqrt((double) num) + 1; ulong limit = (ulong) native_sqrt((double) num) + 1;
if (num < 3 || num % 2 == 0) { if (num < 3 || num % 2 == 0) {
prime = false; return;
} else { } else {
for (uint i = 0; i < LOWER_PRIME_COUNT; i++) { for (uint i = 0; i < LOWER_PRIME_COUNT; i++) {
if (LOWER_PRIMES[i] >= limit) { if (LOWER_PRIMES[i] >= limit) {
break; break;
} }
if (num % LOWER_PRIMES[i] == 0) { if (num % LOWER_PRIMES[i] == 0) {
prime = false; return;
break;
} }
} }
ulong start = LOWER_PRIMES[LOWER_PRIME_COUNT - 1]; }
if (prime && start < limit) { OUT[id] = true;
start -= start % 3; }
if (start % 2 == 0) { __kernel void check_prime(__global const ulong *IN, __global bool *OUT) {
start -= 3; uint id = get_global_id(0);
} ulong num = IN[id];
for (ulong i = start; i <= limit; i += 6) { ulong limit = (ulong) native_sqrt((double) num) + 1;
if (num % (i - 2) == 0 || num % (i - 4) == 0) {
prime = false; if (num < 3 || num % 2 == 0) {
break; return;
} } else {
for (ulong i = 9; i <= limit; i += 6) {
if (num % (i - 2) == 0 || num % (i - 4) == 0) {
return;
} }
} }
} }
OUT[id] = prime; OUT[id] = true;
} }

@ -46,7 +46,12 @@ impl KernelController {
} }
pub fn filter_primes(&self, input: Vec<u64>) -> ocl::Result<Vec<u64>> { pub fn filter_primes(&self, input: Vec<u64>) -> ocl::Result<Vec<u64>> {
lazy_static::lazy_static! {static ref PRIME_CACHE: Arc<Mutex<Vec<u64>>> = Arc::new(Mutex::new(get_primes(2048)));} lazy_static::lazy_static! {static ref PRIME_CACHE: Arc<Mutex<Vec<u64>>> = Arc::new(Mutex::new(Vec::new()));}
if PRIME_CACHE.lock().len() == 0 {
PRIME_CACHE.lock().append(&mut get_primes(
(*input.iter().max().unwrap_or(&1024) as f64).sqrt().ceil() as u64,
));
}
let prime_buffer = self let prime_buffer = self
.pro_que .pro_que
@ -68,7 +73,7 @@ impl KernelController {
let kernel = self let kernel = self
.pro_que .pro_que
.kernel_builder("check_prime") .kernel_builder("check_prime_cached")
.arg(prime_buffer.len() as u32) .arg(prime_buffer.len() as u32)
.arg(&prime_buffer) .arg(&prime_buffer)
.arg(&input_buffer) .arg(&input_buffer)
@ -120,15 +125,17 @@ impl KernelController {
} }
/// Returns a list of prime numbers that can be used to speed up the divisibility check /// Returns a list of prime numbers that can be used to speed up the divisibility check
fn get_primes(count: usize) -> Vec<u64> { fn get_primes(max_number: u64) -> Vec<u64> {
let start = Instant::now(); let start = Instant::now();
let mut primes = Vec::with_capacity(count); let mut primes = Vec::with_capacity((max_number as f64).sqrt() as usize);
let mut num = 3; let mut num = 3;
while primes.len() < count { while num < max_number {
let mut is_prime = true; let mut is_prime = true;
if num < 3 || num % 2 == 0 { if num == 2 {
is_prime = true;
} else if num < 3 || num % 2 == 0 {
is_prime = false; is_prime = false;
} else { } else {
let check_stop = (num as f64).sqrt().ceil() as u64; let check_stop = (num as f64).sqrt().ceil() as u64;
@ -162,7 +169,7 @@ fn get_primes(count: usize) -> Vec<u64> {
} }
println!( println!(
"Generated {} primes on the cpu in {} ms", "Generated {} primes on the cpu in {} ms",
count, primes.len(),
start.elapsed().as_secs_f64() * 1000f64 start.elapsed().as_secs_f64() * 1000f64
); );

@ -78,6 +78,7 @@ fn calculate_primes(prime_opts: CalculatePrimes, controller: KernelController) -
if offset % 2 == 0 { if offset % 2 == 0 {
offset += 1; offset += 1;
} }
sender.send(vec![2]).unwrap();
loop { loop {
let start = Instant::now(); let start = Instant::now();
let numbers = (offset..(prime_opts.numbers_per_step as u64 * 2 + offset)) let numbers = (offset..(prime_opts.numbers_per_step as u64 * 2 + offset))

Loading…
Cancel
Save