I am trying to parelleize Sieve Of Eratosthenes, the idea to do this is this: First find the primes to square root of N. these primes will be evenly distributed to the number of threads. These threas will now for each prime they have cross multiples and mark in a byteArray if the number is prime or not. in the end I will sequentially go through this byte array and collect all the values that are prime.
The problem I am facing is, that the number of primes that are found are not correct, and that there must be a synch problem somewhere I cannot see since the numOfPrimes changes everytime
I will paste the code as much as I can.
public class Para_SieveOfEratosthenes {
static int number_to_find_primes = 2000000;
static int square_of_num = (int) Math.sqrt(number_to_find_primes);
static int square_of_square = (int) Math.sqrt(square_of_num);
static int cells = (number_to_find_primes / 16) + 1;
static public byte[] byteArray2 = new byte[cells];
static int num_of_threads = 3;
static int numOfPrimes = 2;
In the main I am using first another method in another class to find the primes. I thought maybe this might be the problem, because maybe the crossing of in the byte array done in this method does not go over to byteArray2?
public static void main(String[] args) {
SieveOfEratosthenes seqSiev = new SieveOfEratosthenes(square_of_square);
int[] primes = seqSiev.getPrimes();
//Get the num of primes found in the seq algo
numOfPrimes += primes.length;
This part of the code seems all good since it divides the primes evenly and creates the threads as they should
Thread[] threads = new Thread[num_of_threads];
int primes_per_thread = primes.length / num_of_threads;
int extra_primes = primes.length % num_of_threads;
int start_index = 0;
int end_index = 0;
int value_length = number_to_find_primes / num_of_threads;
for (int i = 0; i < num_of_threads; i++, extra_primes--) {
start_index = end_index;
end_index = start_index + primes_per_thread + (extra_primes > 0 ? 1 : 0);
int[] thread_primes = Arrays.copyOfRange(primes, start_index, end_index);
threads[i] = new Thread(new SieveWorker(i,thread_primes));
}
I now start the threads and wait for the join, and then collect the primes
for (int i = 0; i < num_of_threads; i++) {
threads[i].start();
}
for (int i = 0; i < num_of_threads; i++) {
try { threads[i].join(); } catch (InterruptedException e) {}
}
int[] arr=collectPrimes();
System.out.println(arr.length);
This is the collectPrime method, it is taken from the SieveOfEratosthenes, which is promissed to be correct since its the precode
private static int[] collectPrimes() {
int start = (square_of_num % 2 == 0) ? square_of_num + 1 : square_of_num + 2;
for (int i = start; i <= number_to_find_primes; i += 2){
if (isPrime(i))
numOfPrimes++;
}
System.out.println(numOfPrimes);
int[] primes = new int[numOfPrimes];
primes[0] = 2;
int j = 1;
for (int i = 3; i <= number_to_find_primes; i += 2)
if (isPrime(i))
{
primes[j++] = i;
}
return primes;
}
This is the thread Class:
static class SieveWorker implements Runnable{
public int id;
public int[] work;
public int num_primes;
public int value_start;
public int value_end = number_to_find_primes;
public SieveWorker(int id,int[] work ){
this.id = id;
this.work = work;
}
@Override
public void run() {
for (int i = 0; i < work.length; i++) {
this.value_start = work[i];
sieve(work[i]);
}}
These are the methods that does the sieve
static void sieve(int prime) {
//System.out.println("We are traversing: "+prime);
while (prime != -1) {
traverse(prime);
prime = nextPrime(prime);
numOfPrimes++;
}}
private static void traverse(int prime) {
for (int i = prime*prime; i <= number_to_find_primes; i += prime * 2)
mark(i);
}
private static void mark(int num) {
int bitIndex = (num % 16) / 2;
int byteIndex = num / 16;
byteArray2[byteIndex] |= (1 << bitIndex);
}
private static int nextPrime(int prev) {
for (int i = prev + 2; i <= square_of_num; i += 2)
if (isPrime(i))
return i;
return -1;
}
If anyone has any idea on where the mistake is, I would really appreciate a comment, not sure how to make this post smaller without loosing the value of the code. Thank you