#include <stdio.h> |
#include <math.h> |
#include <stdlib.h> |
#include <unistd.h> |
#include <gsl/gsl_rng.h> |
#include <gsl/gsl_randist.h> |
#include “mpi.h” |
#define OUT_FILE “out_mpi.txt” |
//number of Monte-Carlo (MC) simulations in each process |
#define MC 100 |
#define N 10000 //number of clients |
#define M 5 //number of phases |
#define NP 10 //number of MPI processes |
void print_results(double results, double time, int lambda) { |
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]); |
time = MPI_Wtime() − time; |
fprintf(fp, “%fn”, time); |
for (int i = 0; i < MC NP − 1; i++) fprintf(fp, “%f%s”, results[i], “,”); |
fprintf(fp, “%fn”, results[MC NP − 1]); |
fclose(fp); |
} |
void process(int numprocs, int myid, gsl_rng ran, int lambda) { |
double time = MPI_Wtime(); //start time |
double tau[MC] = {0}; //interarrival time |
double st[MC] = {0}; //sojourn time |
//sojourn time of the previous customer in each phase |
double st_prev[M][MC] = 0; |
double results[MC NP] = {0}; //overall results |
for (int j = 0; j < MC; j++) { |
//init each MC trial |
tau[j] = gsl_ran_exponential(ran, 1.0/lambda0); |
st[j] = 0; |
for (int i = 0; i < M; i++) |
for (int j = 0; j < MC; j++) st_prev[i][j] = 0.; |
for (int i = 0; i < N; i++) { |
for (int t = 0; t < M; t++) { |
//recurrent equation |
st[j] += gsl_ran_exponential(ran, 1.0/lambda[t + 1]) + fmax(0.0, st_prev[t][j] − st[j] − tau[j]); |
st_prev[t][j] = st[j]; |
|
MPI_Gather(&st, MC, MPI_DOUBLE, &results, MC, MPI_DOUBLE, 0, MPI_COMM_WORLD); |
if (myid == 0) { |
print_results(&results0, time, &lambda0); |
|
int main(int argc, char argv) { |
int namelen; |
char processor_name[MPI_MAX_PROCESSOR_NAME]; |
int numprocs; |
int myid; |
gsl_rng ran; //random generator |
//parameter of the exponential distribution |
int lambda[M + 1] = {0}; |
//init mpi |
MPI_Init(&argc, &argv); |
MPI_Comm_size(MPI_COMM_WORLD, &(numprocs)); |
MPI_Comm_rank(MPI_COMM_WORLD, &(myid)); |
MPI_Get_processor_name(processor_name, &namelen); |
//init parameter for the exponential distribution |
lambda0 = 30000; |
for (int i = 1; i < M; i++)lambda[i] = lambda[i − 1] − 25000/M; |
lambda[M] = 5000; |
fprintf(stdout, “Process %d of %d is on %sn”, myid, numprocs, processor_name); |
fflush(stdout); |
//init random generator |
gsl_rng_env_setup(); |
ran = gsl_rng_alloc(gsl_rng_ranlxs2); |
gsl_rng_set(ran, (long) (myid) 22); |
//process |
process(numprocs, myid, ran, lambda); |
//finish |
gsl_rng_free(ran); |
MPI_Finalize(); |
return (0); |
} |