Sieve eratosthenes parallelisation in c with pthreads

52 Views Asked by At

I tried to implement the parallelisation of Sieve eratosthenes. And i think it works well but when i try to compare execution time for different number of threads. I dont really understand my results :

My implementation

#include <math.h>
#include <pthread.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

int N;
int k;

int *primes_array;
pthread_t *thread_array;

void *thread_execution(void *thread_index) {
  int start;
  int end;
  int index = *(int *)thread_index;
  for (int i = 2; i * i < N; i++) {
    int nb_max_i = ceil(((N) - (i * i)) / i);

    start = ceil(i * i + (nb_max_i * index / k) * i);
    end = ceil(i * i + (nb_max_i * (index + 1) / k) * i);

    for (int j = start; j <= end; j += i) {
      primes_array[j] = 0;
    }
  }
  pthread_exit(NULL);
}

int main(int argc, char *argv[]) {

  if (argc < 3) {
    printf("Please provide two input values.\n");
    return 1;
  }

  N = atoi(argv[1]);
  k = atof(argv[2]);

  primes_array = malloc(sizeof(int) * (N + 1));
  thread_array = malloc(sizeof(pthread_t) * k);

  clock_t t;
  t = clock();

  // Initialisation de primes_array
  for (int i = 2; i < N; i++) {
    primes_array[i] = 1;
  }

  // Création des threads
  for (int i = 0; i < k; i++) {
    int *thread_index = malloc(sizeof(int));
    *thread_index = i;
    if ((pthread_create(&(thread_array[i]), NULL, thread_execution,
                        thread_index))) {
      fprintf(stderr, "pthread_create error \n");
      exit(EXIT_FAILURE);
    }
  }

  for (int w = 0; w < k; w++) {
    pthread_join(thread_array[w], NULL);
  }

  double time_taken = ((double)t) / CLOCKS_PER_SEC;

  int total = 0;
  for (int l = 2; l < N; l++) {
    if (primes_array[l] == 1) {
      //printf("%d ", l);
      total++;
    }
  }
  //printf("\nN = %d, %d thread(s), Total primes %d, Execution time %f \n", N, k,
  //       total, time_taken);
  printf("%f\n", time_taken);

  return 0;
}

Sequential version

#include <math.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>


uint *initArray(uint size) {
  uint *array = (uint *)malloc(size * sizeof(uint));
  if (array == NULL)
    perror("Malloc error!");
  for (uint i = 2; i < size; i++) {
    array[i] = 1;
  }
  return (array);
}

void printPrimes(uint *array, uint size) {
  for (uint i = 0; i < size; i++) {
    if (array[i] == 1) {
      printf("%d ", i);
    }
  }
  printf("\n");
}

void sieveEratosthenes(uint *array, uint n) {

  for (uint i = 0; i < sqrt(n); i++) {
    if (array[i] == 1) {
      for (uint j = i * i; j < n; j += i) {
        array[j] = 0;
      }
    }
  }
}

int main(int argc, char *argv[]) {

  uint n;
  
  if (argc < 2) {
    printf("Please provide  input value.\n");
    return 1;
  }

  n = atoi(argv[1]);

  clock_t t;
  t = clock();

  uint *primesArray = initArray(n);
  sieveEratosthenes(primesArray, n);

  double time_taken = ((double)t) / CLOCKS_PER_SEC;
  
  printf("%f\n", time_taken);

  // printf("Liste des nombres premiers < %d :\n", n);
  int total = 0;
  for (uint i = 0; i < n; i++) {
    if (primesArray[i] == 1) {
      //printf("%d ", i);
      total++;
    }
  }
  //printf("Total %d \n",total );
  // printPrimes(primesArray, n);
  free(primesArray);
  return 0;
}

And i did some scripting to compare the time execution

#!/bin/bash

read -p "Taille du crible : " N
read -p "Nombre d'itérations : " iterations


for (( NUM_THREADS=1; NUM_THREADS<=7;NUM_THREADS++  ))
do
for (( i=1; i<=$iterations; i++ ))
do
  ./eratosthenes_multithreading $N $NUM_THREADS
done > time_exe.txt

sum=$(cat time_exe.txt | awk '{ sum += $1 } END { print sum }')
count=$(cat time_exe.txt | wc -l)
mean=$(echo "scale=7; $sum / $count" | bc)

echo "Mean exec ($iterations iterations), N = $N, $NUM_THREADS thread(s) --> $mean sec" >> output.txt
done

The result : enter image description here

How can i interpret the results ?

for info : CPU: Intel i7-7500U (4) @ 3.500GHz

i tried to increase the number of iterations but nothing really changed

0

There are 0 best solutions below