| 1 | /******************************************************************************
|
|---|
| 2 | C-DAC Tech Workshop : hyPACK-2013
|
|---|
| 3 | October 15-18,2013
|
|---|
| 4 |
|
|---|
| 5 | Example : pthread-numerical-integration.c
|
|---|
| 6 |
|
|---|
| 7 | Objective : Calculate the Pi Value using simple Integration
|
|---|
| 8 |
|
|---|
| 9 | Input : Number Of Intervals
|
|---|
| 10 |
|
|---|
| 11 | Output : Pi Value computed using simple Integration
|
|---|
| 12 | Time Taken for Pi Computation(in Seconds).
|
|---|
| 13 |
|
|---|
| 14 | Created : MAY-2013
|
|---|
| 15 | E-mail : hpcfte@cdac.in
|
|---|
| 16 |
|
|---|
| 17 | *******************************************************************************/
|
|---|
| 18 |
|
|---|
| 19 | #include<pthread.h>
|
|---|
| 20 | #include<stdlib.h>
|
|---|
| 21 | #include<stdio.h>
|
|---|
| 22 | #include<math.h>
|
|---|
| 23 | #include<sys/time.h>
|
|---|
| 24 |
|
|---|
| 25 | #define MAX_THREADS 8
|
|---|
| 26 | #define MAX_ITERATIONS 10000
|
|---|
| 27 | #define Actual_pi 3.14159265388372456789123456789456
|
|---|
| 28 | #define tolerance 1.0E-15
|
|---|
| 29 |
|
|---|
| 30 | void *compute_pi (void *);
|
|---|
| 31 |
|
|---|
| 32 | double intervalWidth, intervalMidPoint, area = 0.0;
|
|---|
| 33 | int numberOfIntervals, interval, iCount,iteration, num_threads;
|
|---|
| 34 | double distance=0.5,four=4.0;
|
|---|
| 35 |
|
|---|
| 36 | /* Create a MutEx for area. */
|
|---|
| 37 |
|
|---|
| 38 | pthread_mutex_t area_mutex=PTHREAD_MUTEX_INITIALIZER;
|
|---|
| 39 | pthread_mutex_t pi_mutex=PTHREAD_MUTEX_INITIALIZER;
|
|---|
| 40 |
|
|---|
| 41 | /* Thread callback function */
|
|---|
| 42 | void myPartOfCalc(int myID)
|
|---|
| 43 | {
|
|---|
| 44 |
|
|---|
| 45 | int myInterval;
|
|---|
| 46 | double myIntervalMidPoint, myArea = 0.0, result;
|
|---|
| 47 |
|
|---|
| 48 | for (myInterval = myID + 1; myInterval <= numberOfIntervals; myInterval += numberOfIntervals)
|
|---|
| 49 | {
|
|---|
| 50 | myIntervalMidPoint = ((double) myInterval - distance) * intervalWidth;
|
|---|
| 51 | myArea += (four / (1.0 + myIntervalMidPoint * myIntervalMidPoint));
|
|---|
| 52 | }
|
|---|
| 53 |
|
|---|
| 54 | result = myArea * intervalWidth;
|
|---|
| 55 |
|
|---|
| 56 |
|
|---|
| 57 | /* Lock the mutex controlling the access to area. */
|
|---|
| 58 |
|
|---|
| 59 | pthread_mutex_lock(&area_mutex);
|
|---|
| 60 |
|
|---|
| 61 | area += result;
|
|---|
| 62 |
|
|---|
| 63 | pthread_mutex_unlock(&area_mutex);
|
|---|
| 64 |
|
|---|
| 65 | }
|
|---|
| 66 |
|
|---|
| 67 | /* Main function starts */
|
|---|
| 68 | int main(int argc, char *argv[])
|
|---|
| 69 | {
|
|---|
| 70 | /*variable declartion */
|
|---|
| 71 | int i,Iteration,ret_count;
|
|---|
| 72 | pthread_t p_threads[MAX_THREADS];
|
|---|
| 73 | pthread_t * threads;
|
|---|
| 74 | pthread_attr_t pta;
|
|---|
| 75 | pthread_attr_t attr;
|
|---|
| 76 | double computed_pi,diff;
|
|---|
| 77 | double time_start, time_end;
|
|---|
| 78 | struct timeval tv;
|
|---|
| 79 | struct timezone tz;
|
|---|
| 80 | FILE *fp;
|
|---|
| 81 | int CLASS_SIZE,THREADS;
|
|---|
| 82 | char * CLASS;
|
|---|
| 83 | /* Declare a pointer to pthread to create dynamically. */
|
|---|
| 84 |
|
|---|
| 85 | ret_count=pthread_mutex_init(&area_mutex,NULL);
|
|---|
| 86 | if (ret_count)
|
|---|
| 87 | {
|
|---|
| 88 | printf("ERROR; return code from pthread_mutex_init() is %d\n", ret_count);
|
|---|
| 89 | exit(-1);
|
|---|
| 90 | }
|
|---|
| 91 |
|
|---|
| 92 | /*calculating start time */
|
|---|
| 93 | gettimeofday(&tv, &tz);
|
|---|
| 94 | time_start = (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0;
|
|---|
| 95 |
|
|---|
| 96 | printf("\n\t\t---------------------------------------------------------------------------");
|
|---|
| 97 | printf("\n\t\t Centre for Development of Advanced Computing (C-DAC)");
|
|---|
| 98 | printf("\n\t\t Email : hpcfte@cdac.in");
|
|---|
| 99 | printf("\n\t\t---------------------------------------------------------------------------");
|
|---|
| 100 | printf("\n\t\t Objective : PI Computations");
|
|---|
| 101 | printf("\n\t\t Computation of PI using Numerical Integration Method ");
|
|---|
| 102 | printf("\n\t\t..........................................................................\n");
|
|---|
| 103 |
|
|---|
| 104 | if( argc != 2 ){
|
|---|
| 105 |
|
|---|
| 106 | printf("\t\t Very Few Arguments\n ");
|
|---|
| 107 | printf("\t\t Syntax : exec <Number of Intervals>\n");
|
|---|
| 108 | return 0;
|
|---|
| 109 | }
|
|---|
| 110 | else {
|
|---|
| 111 | numberOfIntervals = atoi(argv[1]);
|
|---|
| 112 | }
|
|---|
| 113 | if(numberOfIntervals > MAX_THREADS) {
|
|---|
| 114 | printf("\n Number Of Intervals should be less than or equal to 8.Aborting\n");
|
|---|
| 115 | return 0;
|
|---|
| 116 | }
|
|---|
| 117 |
|
|---|
| 118 | num_threads = numberOfIntervals ;
|
|---|
| 119 | printf("\n\t\t Input Parameters :");
|
|---|
| 120 | printf("\n\t\t Number Of Intervals : %d ",numberOfIntervals);
|
|---|
| 121 |
|
|---|
| 122 | /***********************************Simple Integration Method Starts************************************************/
|
|---|
| 123 | ret_count=pthread_attr_init(&pta);
|
|---|
| 124 | if(ret_count)
|
|---|
| 125 | {
|
|---|
| 126 | printf("\n ERROR : Return code from pthread_attr_init() is %d ",ret_count);
|
|---|
| 127 | exit(-1);
|
|---|
| 128 | }
|
|---|
| 129 | if (numberOfIntervals == 0)
|
|---|
| 130 | {
|
|---|
| 131 | printf("\nNumber of Intervals are assumed to be 8");
|
|---|
| 132 | numberOfIntervals = 8;
|
|---|
| 133 | }
|
|---|
| 134 |
|
|---|
| 135 | threads = (pthread_t *) malloc(sizeof(pthread_t) * numberOfIntervals);
|
|---|
| 136 |
|
|---|
| 137 | /* Calculate Interval Width. */
|
|---|
| 138 | intervalWidth = 1.0 / (double) numberOfIntervals;
|
|---|
| 139 |
|
|---|
| 140 | /* Now Compute Area. */
|
|---|
| 141 | for (iCount = 0; iCount < num_threads; iCount++)
|
|---|
| 142 | {
|
|---|
| 143 |
|
|---|
| 144 | ret_count=pthread_create(&threads[iCount], &pta, (void *(*) (void *)) myPartOfCalc, (void *) iCount);
|
|---|
| 145 | if (ret_count)
|
|---|
| 146 | {
|
|---|
| 147 | printf("ERROR; return code from pthread_create() is %d\n", ret_count);
|
|---|
| 148 | exit(-1);
|
|---|
| 149 | }
|
|---|
| 150 | }
|
|---|
| 151 |
|
|---|
| 152 | for (iCount = 0; iCount < numberOfIntervals; iCount++)
|
|---|
| 153 | {
|
|---|
| 154 | ret_count=pthread_join(threads[iCount], NULL);
|
|---|
| 155 | if (ret_count)
|
|---|
| 156 | {
|
|---|
| 157 | printf("ERROR; return code from pthread_join() is %d\n", ret_count);
|
|---|
| 158 | exit(-1);
|
|---|
| 159 | }
|
|---|
| 160 | }
|
|---|
| 161 | /* Print the results. */
|
|---|
| 162 | ret_count=pthread_attr_destroy(&pta);
|
|---|
| 163 | if (ret_count)
|
|---|
| 164 | {
|
|---|
| 165 | printf("ERROR; return code from pthread_attr_destroy() is %d\n", ret_count);
|
|---|
| 166 |
|
|---|
| 167 | exit(-1);
|
|---|
| 168 | }
|
|---|
| 169 |
|
|---|
| 170 |
|
|---|
| 171 | /**********************************Simple Integration Method Ends*****************************************************/
|
|---|
| 172 |
|
|---|
| 173 | gettimeofday(&tv, &tz);
|
|---|
| 174 | time_end = (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0;
|
|---|
| 175 | printf("\n\t\t Computation Of PI value Using Numerical Integration Method ......Done\n");
|
|---|
| 176 | printf("\n\t\t Computed Value Of PI : %lf", area);
|
|---|
| 177 | printf("\n\t\t Time in Seconds (T) : %lf", time_end - time_start);
|
|---|
| 178 | printf("\n\t\t..........................................................................\n");
|
|---|
| 179 | free(threads);
|
|---|
| 180 |
|
|---|
| 181 | }
|
|---|