Research Article

Teaching Scientific Computing: A Model-Centered Approach to Pipeline and Parallel Programming with C

Listing 4

#include <stdio.h>
#include <math.h>
#include <gsl/gsl_rng.h>
#include <gsl/gsl_randist.h>
#include <omp.h>
#define OPENMP 12
#define OUT_FILE “out_openmp.txt”
//number of Monte-Carlo simulations in one thread
#define MC 200
#define N 10000 //number of clients
#define M 5 //number of phases
//parameters of the exponential distribution
int lambda[M + 1]  =  {0};
double tau  =  0; //interarrival time
double st  =  0; //sojourn time
//sojourn time for the previous client
double st_prev[M]  =  {0};
//results- sojourn time for all threads trials
double results[MC OPENMP]  =  {0};
//results- sojourn time for each thread trial
double th_results[MC]  =  {0};
gsl_rng ran; //random generator
int main(int argc, char argv) {
lambda0  =  30000;
for (int i  =  1; i < M; i++)lambda[i]  =  lambda[i − 1] − 25000/M;
lambda[M]  =  5000;
unsigned long int i, t, j;
int th_id; //thread number
#pragma omp parallel num_threads(OPENMP)
private(th_id, ran, j, i, t, tau, st, st_prev)
firstprivate(th_results) shared(results,lambda)
{
th_id  =  omp_get_thread_num();
//printf(“Hello World from the thread %dn”, th_id);
gsl_rng_env_setup();
ran  =  gsl_rng_alloc(gsl_rng_ranlxs2);
gsl_rng_set(ran, (long) th_id 22); //seed
for (j  =  0; j < MC; j++) {
tau  =  gsl_ran_exponential(ran, 1.0/lambda0);
st  =  0.;
for (i  =  0; i < M; i++) st_prev[i]  =  0.;
for (i  =  0; i < N; i++) {
for (t  =  0; t < M; t++) {
//recurrent equation
st += gsl_ran_exponential(ran, 1.0/lambda[t + 1]) + fmax(0.0, st_prev[t] − st − tau);
st_prev[t]  =  st;
th_results [j]  =  st;
}
for (i  =  0; i < MC; i++) results[i + th_id MC]  =  th_results [i];
gsl_rng_free(ran);
}
//printing results
FILE fp;
const char DATA_FILE  =  OUT_FILE;
fp  =  fopen(DATA_FILE, “w”);
fprintf(fp, “%d%s%d%s%dn”, N, “,”, lambda0, “,”, lambda[M]);
for (i  =  0; i < MC OPENMP − 1; i++) fprintf(fp, “%f%s”, results[i], “,”);
fprintf(fp, “%fn”, results[MC OPENMP − 1]);
fclose(fp);
return EXIT_SUCCESS;                        
}