Skip to content
prng_omp.c 1.83 KiB
Newer Older
#include <stdio.h> // printf
#include <stdlib.h> // EXIT_SUCCESS
#include <omp.h>

#include "prng_shared.h"

int main(int argc, char* argv[]) {
    int seed;
    int N;
    int i;
    int number_of_workers;
    int my_seed;
    int my_i;
    int my_thread_id;
    double *seq;


    // get parameters from command line arguments
    read_arguments(&seed, &N, argc, argv);

    // allocate and array to hold N random numbers
    seq = malloc(N * sizeof(double));
    // exit if allocation fails
    if (seq == NULL) {
        printf("Cannot allocate space for %d numbers\n", N);
        exit(EXIT_FAILURE);
    }

    // create OMP_NUM_THREADS threads
    // every thread will have its own my_i, my_thread_id and  my_seed variables
    // the computer will run number_of_workers different for loops concurrently,
    // one for each thread, and threads will alter the same seq array.
    // however, due to the striding access patterns, areas affected by different
    // threads will not overlap, and race conditions are avoided
#pragma omp parallel private (my_i, my_thread_id, my_seed)
    {
        // get number of threads
        number_of_workers = omp_get_num_threads();
    
        // exit if work cannot be divided equally among workers
        if ( (N % number_of_workers) != 0 ) {
            printf("Cannot equally divide %d numbers by %d workers \n", N, number_of_workers);
            exit(EXIT_FAILURE);
        }
    
        my_thread_id = omp_get_thread_num();
        my_seed = seed + omp_get_thread_num();
    
        for (my_i = my_thread_id; my_i < N; my_i += number_of_workers) {
            seq[my_i] = (double)rand_r(&my_seed) / (double)RAND_MAX;
        }

    }

    // print the generated random numbers, showing 8 digits after the decimal point
    for (i=0; i<N; i++) {
        printf("%10.8lf\n", seq[i]);
    }

    return EXIT_SUCCESS;

}