SHARE
TWEET

Untitled

a guest Nov 22nd, 2019 77 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top