Advertisement
Guest User

Untitled

a guest
Jan 26th, 2015
187
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.61 KB | None | 0 0
  1. /* matrix summation using pthreads
  2.  
  3. features: uses a barrier; the Worker[0] computes
  4. the total sum from partial sums computed by Workers
  5. and prints the total sum to the standard output
  6.  
  7. usage under Linux:
  8. gcc matrixSum.c -lpthread
  9. a.out size numWorkers
  10.  
  11. */
  12. #ifndef _REENTRANT
  13. #define _REENTRANT
  14. #endif
  15. #include <pthread.h>
  16. #include <stdlib.h>
  17. #include <stdio.h>
  18. #include <stdbool.h>
  19. #include <time.h>
  20. #include <sys/time.h>
  21. #define MAXSIZE 10000 /* maximum matrix size */
  22. #define MAXWORKERS 10 /* maximum number of workers */
  23.  
  24. pthread_mutex_t barrier; /* mutex lock for the barrier */
  25. pthread_mutex_t minMax; /* mutex lock for min and max */
  26. pthread_cond_t go; /* condition variable for leaving */
  27. int numWorkers; /* number of workers */
  28. int numArrived = 0; /* number who have arrived */
  29.  
  30. /* a reusable counter barrier */
  31. void Barrier() {
  32. pthread_mutex_lock(&barrier);
  33. numArrived++;
  34. if (numArrived == numWorkers) {
  35. numArrived = 0;
  36. pthread_cond_broadcast(&go);
  37. } else
  38. pthread_cond_wait(&go, &barrier);
  39. pthread_mutex_unlock(&barrier);
  40. }
  41.  
  42. /* timer */
  43. double read_timer() {
  44. static bool initialized = false;
  45. static struct timeval start;
  46. struct timeval end;
  47. if( !initialized )
  48. {
  49. gettimeofday( &start, NULL );
  50. initialized = true;
  51. }
  52. gettimeofday( &end, NULL );
  53. return (end.tv_sec - start.tv_sec) + 1.0e-6 * (end.tv_usec - start.tv_usec);
  54. }
  55.  
  56. double start_time, end_time; /* start and end times */
  57. int size, stripSize; /* assume size is multiple of numWorkers */
  58. int sums[MAXWORKERS]; /* partial sums */
  59. int matrix[MAXSIZE][MAXSIZE]; /* matrix */
  60. int min[3];
  61. int max[3];
  62.  
  63. void *Worker(void *);
  64.  
  65. /* read command line, initialize, and create threads */
  66. int main(int argc, char *argv[]) {
  67. int i, j;
  68. long l; /* use long in case of a 64-bit system */
  69. pthread_attr_t attr;
  70. pthread_t workerid[MAXWORKERS];
  71.  
  72. /* set global thread attributes */
  73. pthread_attr_init(&attr);
  74. pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
  75.  
  76. /* initialize mutex and condition variable */
  77. pthread_mutex_init(&barrier, NULL);
  78. pthread_mutex_init(&minMax, NULL);
  79. pthread_cond_init(&go, NULL);
  80.  
  81. /* read command line args if any */
  82. size = (argc > 1)? atoi(argv[1]) : MAXSIZE;
  83. numWorkers = (argc > 2)? atoi(argv[2]) : MAXWORKERS;
  84. if (size > MAXSIZE) size = MAXSIZE;
  85. if (numWorkers > MAXWORKERS) numWorkers = MAXWORKERS;
  86. stripSize = size/numWorkers;
  87.  
  88. /* initialize the matrix */
  89. for (i = 0; i < size; i++) {
  90. for (j = 0; j < size; j++) {
  91. matrix[i][j] = rand()%99;
  92. }
  93. }
  94.  
  95. /* inizialize min and max */
  96. for(i = 0; i < 3; i++) {
  97. min[i] = 99999999;
  98. max[i] = 0;
  99. }
  100.  
  101. /* print the matrix */
  102. #ifdef DEBUG
  103. for (i = 0; i < size; i++) {
  104. printf("[ ");
  105. for (j = 0; j < size; j++) {
  106. printf(" %d", matrix[i][j]);
  107. }
  108. printf(" ]\n");
  109. }
  110. #endif
  111.  
  112. /* do the parallel work: create the workers */
  113. start_time = read_timer();
  114. for (l = 0; l < numWorkers; l++)
  115. pthread_create(&workerid[l], &attr, Worker, (void *) l);
  116. pthread_exit(NULL);
  117. }
  118.  
  119. /* Each worker sums the values in one strip of the matrix.
  120. After a barrier, worker(0) computes and prints the total */
  121. void *Worker(void *arg) {
  122. long myid = (long) arg;
  123. int total, i, j, first, last;
  124.  
  125. #ifdef DEBUG
  126. printf("worker %d (pthread id %d) has started\n", myid, pthread_self());
  127. #endif
  128.  
  129. /* determine first and last rows of my strip */
  130. first = myid*stripSize;
  131. last = (myid == numWorkers - 1) ? (size - 1) : (first + stripSize - 1);
  132.  
  133. /* sum values in my strip */
  134. total = 0;
  135. for (i = first; i <= last; i++) {
  136. for (j = 0; j < size; j++) {
  137. total += matrix[i][j];
  138. pthread_mutex_lock(&minMax);
  139. if(min[0] > matrix[i][j]) {
  140. min[0] = matrix[i][j];
  141. min[1] = i;
  142. min[2] = j;
  143. }
  144. if(max[0] < matrix[i][j]) {
  145. max[0] = matrix[i][j];
  146. max[1] = i;
  147. max[2] = j;
  148. }
  149. pthread_mutex_unlock(&minMax);
  150. }
  151. }
  152. sums[myid] = total;
  153. Barrier();
  154. if (myid == 0) {
  155. total = 0;
  156. for (i = 0; i < numWorkers; i++)
  157. total += sums[i];
  158. /* get end time */
  159. end_time = read_timer();
  160. /* print results */
  161. printf("The total is %d\n", total);
  162. printf("The execution time is %g sec\n", end_time - start_time);
  163. printf("Min is %d on pos %d %d\n", min[0], min[1], min[2]);
  164. printf("Max is %d on pos %d %d\n", max[0], max[1], max[2]);
  165. }
  166. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement