Skip to main content
gamedev.net
🔒 Locked

Multi-threaded Help

Started by ashkash 1 reply 750+ views
Original Post
ashkash
ashkash
I have been given c code for a multi-threaded black-scholes financial model. The code is below. In the code below there are a set of threads created and each thread is given seperate arguments to execute code. I need to modify this so that there is one main that initializes the thread_data_array so it does not depend on the number of threads. It can be initialized to an arbitrary number of elements like 25. This thread_data_array will need to store two additional variables: Allocated (1 if computed, 0 if not) and Result (holds final result computed by thread). Then a number of threads need to be spawned for execution. When a thread enters the Black-Scholes function it should try to lock the thread_data_array and check to see if an element requires computation (if Allocated is 0). If so, it should copy the data into the local thread_data variables, unlock the array, and execute. Once done executing, it should lock the array, write back the results and update the allocated variable, and unlock the array. I really do not know how to go about doing this. I am not looking for someone to do my assignment, but just looking for help. Any help is appreciated. I was told that there is not a lot of code that needs to be changed or added to the model below to accomplish the modifications. #include #include #include #include #ifndef Pi #define Pi 3.141592653589793238462643 #endif #define NUM_THREADS 7 char *messages[NUM_THREADS]; struct thread_data { int thread_id; char flag; double stock_price; double strike_price; double years; double rate_risk_free; double volatility; }; struct thread_data thread_data_array[NUM_THREADS]; double CND( double ); void *BlackScholes(void *threadarg) { int taskid; struct thread_data *my_data; double d1, d2; double S, X, T, r, v; char CallPutFlag; my_data = (struct thread_data *)threadarg; taskid = my_data->thread_id; CallPutFlag = my_data->flag; S = my_data->stock_price; X = my_data->strike_price; T = my_data->years; r = my_data->rate_risk_free; v = my_data->volatility; d1=(log(S/X)+(r+v*v/2)*T)/(v*sqrt(T)); d2=d1-v*sqrt(T); if(CallPutFlag == 'c') printf("Thread %d Price =%f\n", taskid, (S*CND(d1)-X * exp(-r*T)*CND(d2))); else if(CallPutFlag == 'p') printf("Thread %d Price =%f\n", taskid, (X*exp(-r * T) * CND(-d2) - S * CND(-d1))); pthread_exit(NULL); } // The cumulative normal distribution function double CND( double X ) { double L, K, w ; double const a1 = 0.31938153, a2 = -0.356563782, a3 = 1.781477937; double const a4 = -1.821255978, a5 = 1.330274429; L = fabs(X); K = 1.0 / (1.0 + 0.2316419 * L); w = 1.0 - 1.0 / sqrt(2 * Pi) * exp(-L *L / 2) * (a1 * K + a2 * K *K + a3 * pow(K,3) + a4 * pow(K,4) + a5 * pow(K,5)); if (X < 0 ){ w= 1.0 - w; } return w; } int main() { pthread_t threads[NUM_THREADS]; int *taskids[NUM_THREADS]; int rc, t; for(t=0;t<NUM_THREADS;t++) { thread_data_array[t].thread_id = t; thread_data_array[t].flag = 'c'; thread_data_array[t].stock_price = 15.0; thread_data_array[t].strike_price = 22.0; thread_data_array[t].years = ((double)rand() / ((double)RAND_MAX + (double)1.0))*15; thread_data_array[t].rate_risk_free = ((double)rand() / ((double)RAND_MAX + (double)1.0))*5; thread_data_array[t].volatility = ((double)rand() / ((double)RAND_MAX + (double)1.0))*1.0; printf("Creating thread %d\n", t); rc = pthread_create(&threads[t], NULL, BlackScholes, (void *) &thread_data_array[t]); if (rc) { printf("ERROR; return code from pthread_create() is %d\n", rc); exit(-1); } } for(t=0; t<NUM_THREADS; t++) { int ret, status; ret = pthread_join(threads[t], (void **)&status); if(ret != 0) { printf("pthread_join: ERROR: t=%d return code =%d\n", t, ret); exit(1); } printf("Joined thread_id = %d\n", t); } pthread_exit(NULL); return 0; }
Palidine
Palidine
Since this is homework you need to pass some hurdle questions before you get help:

1) How long have you thought about the problem?
2) What options have you considered and/or rejected?
3) What ideas do you have for how to do this?

"I really do not know how to go about doing this" generally means: "i've thought about it for a couple minutes and nothing came to mind". Generally complex CS questions take a couple hours of analysis and thought before an answer presents itself. If you were given this as homework then you should have the knowledge & resources to at least make a stab at a solution.

-me
ashkash
ashkash
I know how to initialize the thread_data_array and how to create the threads. The part that is giving me trouble is in the blackscholes function the array needs to be checked for an element with allocated=0 and if this element is found all the data from this element needs to be copied into the local my_data variables. Would something like the code below in the blackscholes function work:

for(int count=0; count<4;count++){
if (thread_data_array[count].allocated = 0)
my_data = (struct thread_data *)threadarg;
taskid = my_data->thread_data_array[count].thread_id;
CallPutFlag = my_data->thread_data_array[count].flag;
S = my_data->thread_data_array[count].stock_price;
X = my_data->thread_data_array[count].strike_price;
T = my_data->thread_data_array[count].years;
r = my_data->thread_data_array[count].rate_risk_free;
v = my_data->thread_data_array[count].volatility;
a = my_data->thread_data_array[count].allocated;
}

The code assumes that the thread_data_array is set to hold 4 elements.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.