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);
ulong num = IN[id];
bool prime = true;
ulong limit = (ulong) native_sqrt((double) num) + 1;
if (num < 3 || num % 2 == 0) {
prime = false;
return;
} else {
for (uint i = 0; i < LOWER_PRIME_COUNT; i++) {
if (LOWER_PRIMES[i] >= limit) {
break;
}
if (num % LOWER_PRIMES[i] == 0) {
prime = false;
break;
return;
}
}
ulong start = LOWER_PRIMES[LOWER_PRIME_COUNT - 1];
}
if (prime && start < limit) {
start -= start % 3;
OUT[id] = true;
}
if (start % 2 == 0) {
start -= 3;
}
for (ulong i = start; i <= limit; i += 6) {
if (num % (i - 2) == 0 || num % (i - 4) == 0) {
prime = false;
break;
}
__kernel void check_prime(__global const ulong *IN, __global bool *OUT) {
uint id = get_global_id(0);
ulong num = IN[id];
ulong limit = (ulong) native_sqrt((double) num) + 1;
if (num < 3 || num % 2 == 0) {
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>> {
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
.pro_que
@ -68,7 +73,7 @@ impl KernelController {
let kernel = self
.pro_que
.kernel_builder("check_prime")
.kernel_builder("check_prime_cached")
.arg(prime_buffer.len() as u32)
.arg(&prime_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
fn get_primes(count: usize) -> Vec<u64> {
fn get_primes(max_number: u64) -> Vec<u64> {
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;
while primes.len() < count {
while num < max_number {
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;
} else {
let check_stop = (num as f64).sqrt().ceil() as u64;
@ -162,7 +169,7 @@ fn get_primes(count: usize) -> Vec<u64> {
}
println!(
"Generated {} primes on the cpu in {} ms",
count,
primes.len(),
start.elapsed().as_secs_f64() * 1000f64
);

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

Loading…
Cancel
Save