Advertisement
Guest User

Untitled

a guest
Nov 22nd, 2019
105
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.18 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <pthread.h>
  4. #include <string.h>
  5.  
  6. /*
  7. This program aims to test the effect of using POSIX threads by testing the performance of using a pthread for each element in the resultant matrix
  8. and by using a pthread for every row. Performance of each case is recorded and compared against the other.
  9. Made by: Marwan Mokhles Abdallah ID #4926
  10. */
  11.  
  12. #define LINE_MAX 512 // CONSTANT DEFINES HOW MANY CHARACTERS
  13. #define MAX_LENGTH 2000 // MAX LENGTH OF THE ARRAY
  14.  
  15. int matA[MAX_LENGTH][MAX_LENGTH]; // INPUT MATRIX 1
  16. int matB[MAX_LENGTH][MAX_LENGTH]; // INPUT MATRIX 2
  17. int matRes[MAX_LENGTH][MAX_LENGTH]; // OUTPUT MATRIX
  18. int r1,c1,r2,c2; // ROW1,COL1,ROW2,COL2
  19.  
  20. char* getCurrentTime(); // UTILITY FUNCTION: RETURNS CURRENT TIME IN STRING FORMAT
  21. void parse2mat(); // CORE FUNCTION: READS AND PARSES INPUT TO MATRIX 1 AND MATRIX 2
  22. void printMat(int matid); // UTILITY FUNCTION: PRINTS A MATRIX IN THE OUTPUT STREAM
  23. int checkValidation(); // UTILITY FUNCTION: CHECKS IF MATRIX 1 AND MATRIX 2 ARE MULTIPLICABLE
  24. void mulElemPerThread(); // CORE FUNCTION: CREATES A THREAD PER OUPTUT MATRIX ELEMENT, AND CALLS A FUNCTION TO CALCULATE ITS VALUE
  25. void* mulElem(void* arg); // CORE FUNCTION: CALCULATES THE VALUE OF AN ELEMENT IN THE OUTPUT MATRIX
  26. void* mulRow(void* arg); // CORE FUNCTION: CALCULATES THE VALUES OF ELEMENTS IN A SINGLE ROW OF THE OUTPUT MATRIX
  27. void mulRowPerThread(); // CORE FUNCTION: CREATES A THREAD PER OUTPUT MATRIX ROW, AND CALLS A FUNCTION TO CALCULATE ITS VALUES
  28. void eraseArrayData(); // UTILITY FUNCTION: ERASES THE OUTPUT MATRIX DATA ONCE THE RESULTS FOR TEST 1 HAS BEEN PRINTED IN THE OUTPUT FILE
  29. void produceOutput(float time, int matid); // CORE FUNCTION: PRINT THE OUTPUT OF TESTS 1 AND 2 IN THE OUTPUT FILE "OUTPUT.TXT"
  30.  
  31. int main()
  32. {
  33. int i=0;
  34. clock_t tstart, tend,tstart2,tend2; // CLOCK VALUES USED TO CALCULATE TIME
  35. FILE *f = fopen("output.txt","w");
  36. if(f)
  37. {
  38. int status = remove("output.txt"); // IF THE FILE IS ALREADY PRESENT, DELETE IT.
  39. }
  40. printf("%s\n",getCurrentTime()); // PRINT THE CURRENT TIME
  41. parse2mat();
  42. int valid = checkValidation(); // CHECK IF MATRIX 1 AND MATRIX 2 ARE VALID FOR MULTIPLICATION
  43. if(valid<0)
  44. {
  45. printf("ERROR: Cannot multiply matA[%d][%d] with matB[%d][%d]. Please enter valid inputs for dimensions!",r1,c1,r2,c2);
  46. exit(-1);
  47. }
  48. tstart2 = clock(); // START CALCULATING TIME FOR TEST 1
  49. pthread_t thread[r1]; // CREATE AN ARRAY OF THREADS OF SIZE R1
  50. mulRowPerThread(); // PERFORM MATRIX MULTIPLICATION WHERE EVERY ELEMENT IS CALCULATED ON ITS OWN IN A SEPARATE THREAD // PERFORM MATRIX MULTIPLICATION WHERE EVERY ROW IS CALCULATED ON ITS OWN IN A SEPARATE THREAD
  51. tend2 = clock(); // STOP CALCULATING TIME FOR TEST 2
  52. produceOutput((tend2 - tstart2)/(double)CLOCKS_PER_SEC,2); // PRINT RESULTS FOR TEST 2 IN THE OUTPUT FILE
  53. printf("\nThe Output Matrix of dimensions [%d][%d] using a thread for each row:\n",r1,c2);
  54. printMat(3);
  55. printf("\nTime Taken: %f s\n", (tend2 - tstart2)/(double)CLOCKS_PER_SEC);
  56. eraseArrayData(); // ERASE OUTPUT MATRIX DATA TO MAKE SPACE FOR TEST 2
  57. tstart = clock();
  58. pthread_t thread1[r1*c2]; // START CALCULATING TIME FOR TEST 1
  59. mulElemPerThread(); // PERFORM MATRIX MULTIPLICATION WHERE EVERY ELEMENT IS CALCULATED ON ITS OWN IN A SEPARATE THREAD
  60. tend = clock(); // STOP CALCULATING TIME FOR TEST 1
  61. produceOutput((tend - tstart)/(double)CLOCKS_PER_SEC,1); // PRINT RESULTS FOR TEST 1 IN THE OUTPUT FILE
  62. printf("\nThe Output Matrix of dimensions [%d][%d] using a thread for each element:\n",r1,c2);
  63. printMat(3);
  64. printf("\nTime Taken: %f s\n", (tend - tstart)/(double)CLOCKS_PER_SEC);
  65. }
  66.  
  67. // CORE FUNCTION: PRINT THE OUTPUT OF TESTS 1 AND 2 IN THE OUTPUT FILE "OUTPUT.TXT"
  68. void produceOutput(float time, int matid)
  69. {
  70. FILE *f;
  71. int i,j;
  72. f = fopen ("output.txt","a");
  73. for(i = 0; i < r1; i++)
  74. {
  75. for(j = 0; j < c2; j++)
  76. {
  77. fprintf(f,"%d\t",matRes[i][j]);
  78. }
  79. fprintf(f,"\n");
  80. }
  81. fprintf(f,"END%d\t%f\n",matid,time);
  82. fclose(f);
  83. }
  84.  
  85. // UTILITY FUNCTION: ERASES THE OUTPUT MATRIX DATA ONCE THE RESULTS FOR TEST 1 HAS BEEN PRINTED IN THE OUTPUT FILE
  86. void eraseArrayData()
  87. {
  88. int i,j;
  89. for(i = 0; i < MAX_LENGTH; i++)
  90. {
  91. for(j = 0; j < MAX_LENGTH; j++)
  92. {
  93. matRes[i][j] = 0;
  94. }
  95. }
  96. }
  97.  
  98. // CORE FUNCTION: CALCULATES THE VALUE OF AN ELEMENT IN THE OUTPUT MATRIX
  99. void* mulElem(void* arg)
  100. {
  101. int* pos = (int*)arg; // CAST THE ARG TO INT* TO RETRIEVE POSITION VALUES
  102. int i=0;
  103. int r = pos[0];
  104. int c = pos[1];
  105. printf("\nreceived: %d %d ",r,c);
  106. for(i = 0; i < c1; i++) // FOR EVERY ELEMENT
  107. {
  108. matRes[r][c] += matA[r][i] * matB[i][c]; // CALCULATE VALUE FOR EACH ELEMENT
  109. }
  110. return NULL;
  111. }
  112.  
  113. // CORE FUNCTION: CREATES A THREAD PER OUPTUT MATRIX ELEMENT, AND CALLS A FUNCTION TO CALCULATE ITS VALUE
  114. void mulElemPerThread(){
  115. int i=0,j=0,k=0,m;
  116. int pos[2];
  117. pthread_t thread[r1*c2]; // CREATE AN ARRAY OF THREADS OF SIZE R1*C2
  118. for(i = 0; i < r1; i++)
  119. {
  120. for(j = 0; j < c2; j++)
  121. {
  122. pos[0]=i;
  123. pos[1]=j;
  124. int ret=pthread_create(&thread[k], NULL, mulElem, pos); // CREATE A THREAD WHOSE FUNCTION IS FUNCTION MULELEM
  125. if(ret)
  126. {
  127. printf("ERROR: Thread not created!");
  128. exit(-1);
  129. }
  130. k++;
  131. }
  132. }
  133. for( m = 0; m < r1*c2 ;m++)
  134. {
  135. pthread_join(thread[m],NULL);
  136. }
  137. }
  138.  
  139. // CORE FUNCTION: CALCULATES THE VALUES OF ELEMENTS IN A SINGLE ROW OF THE OUTPUT MATRIX
  140. void* mulRow(void* args)
  141. {
  142. int row = (int)args;
  143. int i=0,j=0;
  144. for(i = 0; i < c2; i++) // FOR EVERY COLUMN
  145. {
  146. for(j = 0; j < c1; j++)
  147. matRes[row][i] += matA[row][j] * matB[j][i]; // CALCULATE VALUE OF ELEMENT
  148. }
  149. return NULL;
  150. }
  151.  
  152. // CORE FUNCTION: CREATES A THREAD PER OUTPUT MATRIX ROW, AND CALLS A FUNCTION TO CALCULATE ITS VALUES
  153. void mulRowPerThread()
  154. {
  155. int i=0,k=0;
  156. int pos;
  157. pthread_t thread[r1];
  158. for(i = 0; i < r1; i++)
  159. {
  160. pos = i;
  161. int ret=pthread_create(&thread[k++], NULL, mulRow, pos); // CREATE A THREAD WHOSE FUNCTION IS FUNCTION MULROW
  162. if(ret)
  163. {
  164. printf("ERROR: Thread not created!");
  165. exit(-1);
  166. }
  167. }
  168. for(i=0 ; i < r1 ; i++)
  169. {
  170. pthread_join(thread[i],NULL);
  171. }
  172. }
  173.  
  174. // UTILITY FUNCTION: RETURNS CURRENT TIME IN STRING FORMAT
  175. char* getCurrentTime()
  176. {
  177. time_t rawtime;
  178. struct tm * timeinfo;
  179. time ( &rawtime );
  180. timeinfo = localtime (&rawtime);
  181. return asctime (timeinfo);
  182. }
  183.  
  184. // UTILITY FUNCTION: PRINTS A MATRIX IN THE OUTPUT STREAM
  185. void printMat(int matid)
  186. {
  187. int i=0,j=0;
  188. printf("\n");
  189. switch(matid)
  190. {
  191. case 1:
  192. for(i = 0; i < r1; i++)
  193. {
  194. for(j = 0; j < c1; j++)
  195. {
  196. printf("%d\t",matA[i][j]);
  197. }
  198. printf("\n");
  199. }
  200. break;
  201. case 2:
  202. for(i = 0; i < r2; i++)
  203. {
  204. for(j = 0; j < c2; j++)
  205. {
  206. printf("%d\t",matB[i][j]);
  207. }
  208. printf("\n");
  209. }
  210. break;
  211. case 3:
  212. for(i = 0; i < r1; i++)
  213. {
  214. for(j = 0; j < c2; j++)
  215. {
  216. printf("%d\t",matRes[i][j]);
  217. }
  218. printf("\n");
  219. }
  220. break;
  221. }
  222. }
  223.  
  224. // UTILITY FUNCTION: CHECKS IF MATRIX 1 AND MATRIX 2 ARE MULTIPLICABLE
  225. int checkValidation()
  226. {
  227. if(c1!=r2)
  228. return -1;
  229. else
  230. return 1;
  231. }
  232.  
  233. // CORE FUNCTION: READS AND PARSES INPUT TO MATRIX 1 AND MATRIX 2
  234. void parse2mat()
  235. {
  236. FILE *f;
  237. int i,j;
  238. f=fopen("input.txt", "r");
  239. if (f != NULL)
  240. {
  241. if(fscanf(f,"%d %d\n",&r1,&c1)!=-1) // READ 2 INTEGERS (R1,C1) FROM THE FIRST LINE, SEPARATED BY A WHITESPACE
  242. {
  243. for(i = 0; i < r1; i++) // READ INTEGERS ACCORDING TO THE SIZE OF THE MATRIX (R1,C1)
  244. {
  245. for(j = 0; j < c1; j++)
  246. {
  247. if (!fscanf(f, "%d", &matA[i][j]))
  248. break;
  249. }
  250. }
  251. }
  252. printf("\n\nThe Input Matrix A of dimensions R:%d C:%d:\n",r1,c1);
  253. printMat(1);
  254. if(fscanf(f,"%d %d\n",&r2,&c2)!=-1) // READ 2 INTEGERS (R2,C2) FROM THE FIRST LINE, SEPARATED BY A WHITESPACE
  255. {
  256. for(i = 0; i < r2; i++) // READ INTEGERS ACCORDING TO THE SIZE OF THE MATRIX (R2,C2)
  257. {
  258. for(j = 0; j < c2; j++)
  259. {
  260. if (!fscanf(f, "%d", &matB[i][j]))
  261. break;
  262. }
  263. }
  264. }
  265. printf("\n\nThe Input Matrix B of dimensions R:%d C:%d:\n",r2,c2);
  266. printMat(2);
  267. }
  268. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement