Вы находитесь на странице: 1из 10

High Performance Systems Engineering (COMP1574) Coursework ID- 192127

15/04/2012 Md. Zayedur Rahman 000598277-4

Contents
Break down of Application Code: .......................................................................................... 2 Analysis of the expected performance: ................................................................................. 3 Documented Changes: ......................................................................................................... 4 Evidence of testing: ............................................................................................................... 7 Fig 1.1 Execution of the serial version............................................................................ 7 Fig 1.2 Execution of the basic parallel version ............................................................... 7 Fig 1.3 End of the parallel version .................................................................................. 8

Break down of Application Code:


The source code provides runs on a single thread. The execution is described in terms of activities and events. An activity represents a time period of specified length during which some work is performed (calculation or communication). The beginnings and endings of activities are the events in the program (send/receive and process creation/termination events). The serial program when executed does a number of activities. It first does a monte carlo simulation for a prediction NDaysAhead of the profit. Calculates the call payoff, calculates annual Volatility. Then it opens data file provided and reads the data within it. After getting the share prices from data file it computes annual volatility, then continues to do a number of monte carlo simulations. After the simulation is complete it gets the discounted mean of these simulation results and works out the mean of all the discounted rates. And prints out the predicted option price. The potential parallelisation of the source code is to run the code in all processes. And at the end of the simulations averages out the results and sends it to the main processor. Parallel computer programs are more difficult to write than sequential ones, because concurrency introduces several new classes of potential software bugs, of which race conditions are the most common. Communication and synchronization between the different subtasks are typically some of the greatest obstacles to getting good parallel program performance. The maximum possible speed-up of a program as a result of parallelization is observed as Amdahl's law.

Analysis of the expected performance:


The serial code provided takes roughly around 2 minutes (found out using the unix time command) to print out the predicted option price, after an attempt to a basic parallelisation the program took almost the same amount of time to produce the result from multiple threads. If sequential optimisation is used properly with the code, it may be possible to reduce the output time further.

Documented Changes:
The changes are marked in red and explained below:
#include <stdio.h> #include <stdlib.h> #include <math.h> #include <time.h> #include <mpi.h> #define #define #define #define #define #define #define #define #define #define NRepeats 100 NSim 100000 NDaysAhead 41 Strike 500.0 MaxDimDays 1000 RateOfInterest 2.0/100.0 DaysInYear 255.0 DailyDt 1.0/DaysInYear Pi 4.0*atanf(1.0) Epsilon 1.0e-12

double discountedMean(double MCResults[NSim]) { //work out discounted mean of all monte carlo simulation results //first work out the mean of all monte carlo simulation results int i; double sum, mean,temp; sum=0.0; for(i=0; i<NSim; i++) { sum=sum+MCResults[i]; } //mean of monte carlo simulations mean=sum/NSim; //discounted mean=mean*exp(-RateOfInterest*NDaysAhead) temp=-RateOfInterest*NDaysAhead*DailyDt; mean=mean*exp(temp); return (mean); } double monteCarloSimulation(double Spot, double AnnualVol) { //do a monte carlo simulation for a prediction NDaysAhead of the profit (res) int i; double res, temp1, temp2, rand1, rand2; res = Spot; for (i=1; i<=NDaysAhead; i++) { temp1=(RateOfInterest-0.5*AnnualVol*AnnualVol)*DailyDt; rand1=(double)rand()/RAND_MAX; if (rand1 >= 1.0000) { rand1=1.0-Epsilon; } if (rand1 <= 0.0000) { rand1=Epsilon; } rand1=-2.0*(log(rand1)); rand2=2.0*Pi*(double)rand()/RAND_MAX; temp2=AnnualVol*sqrtf(DailyDt)*sqrtf(rand1)*sinf(rand2); res=res*exp(temp1+temp2); } //printf("Simulated price is: %f\n",res); //calc the call payoff as max(res-Strike,0) if(res > Strike) { res=res-Strike; } else { res=0.0; } return (res); }

double calcVolatility(double prices[MaxDimDays], int NDays, double returns[MaxDimDays]) { int i; double sum, mean, sd, Av; //calculate returns as ln(price[i]/price[i-1]) for (i=1; i<=NDays; i++) {

returns[i]=log(prices[i]/prices[i-1]); } //calculate annual Volatility as std_dev(returns)/sqrt(DailyDt) sum=0.0; for (i=1; i<=NDays; i++) { sum=sum+returns[i]; } mean=sum/NDays; sd=0.0; for (i=1; i<=NDays; i++) { sd=sd+(returns[i]-mean)*(returns[i]-mean); } sd=sqrtf(sd/(NDays-1)); Av=sd/sqrtf(DailyDt); return(Av); } void readDataFile(char fname[128], double prices[MaxDimDays], double *Spot, int *NDays) { FILE *fp; int i = 0; double sv; //Open data file provided by fname and read the data within it. if( (fp = fopen(fname, "r")) == NULL ) { printf("Cannot open file.\n"); exit(1); } do { fscanf(fp,"%lf",&sv); prices[i]=sv; printf("Day %d price is %lf\n",i, prices[i]); i++; } while (!feof(fp)); *NDays=i-1; *Spot=prices[0]; printf("Spot price is: %lf\n",*Spot); fclose( fp ); }

int main(int argc,char **argv) { char fname[128]; int num_of_exp, i, NDays,numprocs,proc,myid,done=0; double prices[MaxDimDays], returns[MaxDimDays]; double MCResults[NSim], Discounted[NRepeats]; double Spot, AnnualVol, option_price; MPI_Status status; int master =0; int tag = 123;

/***** Initializations *****/ MPI_Init(&argc,&argv); MPI_Comm_size(MPI_COMM_WORLD,&numprocs); MPI_Comm_rank(MPI_COMM_WORLD,&myid); printf ("MPI task %d has started...\n", myid); srand (time(0)); if ( argc != 2 ) { printf( "usage: %s inputFileName\n", argv[0] ); MPI_Finalize(); return 0; } else { sscanf(argv[1], "%s", &fname); } //get share prices from data file readDataFile(fname, prices, &Spot, &NDays); //compute annual volatilty

AnnualVol = calcVolatility(prices, NDays, returns); printf("Annual Volatility is: %lf\n",AnnualVol); //do a number of monte carlo simulations for(num_of_exp=0; num_of_exp < NRepeats; num_of_exp++) { for(i=0; i<NSim; i++) { MCResults[i] = monteCarloSimulation(Spot, AnnualVol); // printf("MC[%d] is: %f\n",i,MCResults[i]); } //get the discounted mean of these simulation results Discounted[num_of_exp] = discountedMean(MCResults); } /*now work out the mean of all the discounted rates option_price=0.0; for(num_of_exp=0; num_of_exp < NRepeats; num_of_exp++) { option_price=option_price+Discounted[num_of_exp]; } option_price=option_price/(double)NRepeats; //printf("PREDICTED OPTION PRICE is: %lf\n",option_price);*/ } if (myid ==0) { /* if I am the master process gather results from others */ option_price=0.0; for(num_of_exp=0; num_of_exp < NRepeats; num_of_exp++) { MPI_Recv(&num_of_exp,1,MPI_DOUBLE,proc,tag,MPI_COMM_WORLD,&status); option_price=option_price+Discounted[num_of_exp]; } option_price=option_price/(double)NRepeats; printf("PREDICTED OPTION PRICE is: %lf\n",option_price); } else { /* for all the slave processes send results to the master */ printf("Processor %d sending results= %d to master process\n",myid,num_of_exp); MPI_Send(&num_of_exp,1,MPI_DOUBLE,master,tag,MPI_COMM_WORLD); } MPI_Finalize(); return 0; }

Evidence of testing:
The following screenshots are taken during runtime: Fig 1.1 Execution of the serial version

Fig 1.2 Execution of the basic parallel version

Fig 1.3 End of the parallel version

Critical Evaluation:
This attempt to parallelise the serial version of montecarlo is very basic, it can be further improved using various tactics such as sequential optimisation, loop optimisation etc. A basic attempt to parallelise the code was taken but still it is in a very raw form, after conducting a thorough dependence analysis one can see what more could have been done to improve the overall performance and efficiency.

Вам также может понравиться