#include <stdio.h> |
#include <math.h> |
#include <time.h> |
#include <gsl/gsl_rng.h> |
#include <gsl/gsl_randist.h> |
#include <omp.h> |
#define OUT_FILE “out_omp_pipe.txt” |
//total number of Monte-Carlo (MC) simulations |
#define MC 10000 |
#define CMC 100 //chunks per MC axis |
#define N 10000 //total number of clients |
#define M 5 //total number of phases |
#define CN 100 //chunks per clients axis |
#define OPENMP 12 //OMP threads |
//parameters of exponential distributions |
int lambda[M + 1] = {0}; |
//interarrival time for each MC trial |
double tau[MC] = {0}; |
double st[MC] = {0}; //sojourn time |
//sojourn time of the previous client |
//each MC trial and each phase |
double st_prev[MC][M] = 0; |
//aux variable - each MC chunk flag |
int flag[CMC] = {0}; |
//aux variable - each MC chunk counter |
int task_counter[CMC] = {0}; |
int main(int argc, char argv) { |
time_t t1, t2; |
t1 = time(NULL); |
//init exponential distribution parameters |
lambda0 = 30000; |
for (int i = 1; i < M; i++)lambda[i] = lambda[i − 1] − 25000/M; |
lambda[M] = 5000; |
gsl_rng ran; //random generator |
gsl_rng_env_setup(); |
ran = gsl_rng_alloc(gsl_rng_ranlxs2); |
gsl_rng_set(ran, (long) (CN CMC + 10) 22.); //seed |
//set interarrival time for each MC trial |
for (int i = 0; i < MC; i++) |
tau[i] = gsl_ran_exponential(ran, 1.0/lambda0); |
gsl_rng_free(ran); |
omp_set_num_threads(OPENMP); |
#pragma omp parallel //start threads |
{ |
#pragma omp single //one thread to create tasks |
{ |
int i, j, t, c; //aux variables |
int v = 0; //local variable - MC chunk number |
int sum = 0; //local variable - number of tasks |
int while_flag = 1; //var. to stop external while |
//dynamic task creation in each of MC chunks |
while (while_flag) { |
if (!flag[v]) { |
flag[v] = 1; |
//create a new task if previous task had finished |
#pragma omp task default(none)private(i, j, t, c, ran) |
firstprivate(tau, lambda, v, gsl_rng_ranlxs2) |
shared(st, st_prev, flag, task_counter) |
{ |
gsl_rng ran; //random generator for this task |
gsl_rng_env_setup(); |
ran = gsl_rng_alloc(gsl_rng_ranlxs2); |
//seed with the task number |
gsl_rng_set(ran, (long)(task_counter[v] + v CN) 22.); |
for (j = 0; j < MC/CMC; j++) { |
c = j + v (MC/CMC); //MC trial number |
for (i = 0; i < N/CN; i++) { |
for (t = 0; t < M; t++) { |
//recurrent equation |
st[c] += gsl_ran_exponential(ran, 1.0 /lambda[t + 1]) + fmax(0.0, st_prev[c][t] − st[c] − tau[c]); |
st_prev[c][t] = st[c]; |
}}} |
//end of the current task |
gsl_rng_free(ran); |
task_counter[v]++; |
flag[v] = 0; |
}} |
//if all tasks of this chunk of Monte-Carlo trials |
//had finished -then stop this chunk |
//v numbered MC chunk is over |
if (task_counter[v] == CN) flag[v] = 1; |
v++; |
if (v == CMC) v = 0; //again a new loop |
sum = 0; //variable to test all chunks |
for (i = 0; i < CMC; i++) sum += task_counter[i]; |
//if all task had finished - exit while cycle |
if (sum == CN CMC) while_flag = 0; |
}}} |
//print results |
FILE fp; |
const char DATA_FILE = OUT_FILE; |
fp = fopen(DATA_FILE, “w”); |
fprintf(fp, “%d%s%d%s%d%s%dn”, N, “,”, M, “,”, lambda0, “,”, lambda[M]); |
t2 = time(NULL); |
fprintf(fp, “%fn”, difftime(t2, t1)); |
for (int j = 0; j < MC − 1; j++) fprintf(fp, “%f%s”, st[j], “,”); |
fprintf(fp, “%fn”, st[MC − 1]); |
fclose(fp); |
return (0); |
} |