home *** CD-ROM | disk | FTP | other *** search
/ Shareware Supreme Volume 6 #1 / swsii.zip / swsii / 215 / DDJ9208.ZIP / PARA_C.ASC < prev    next >
Text File  |  1992-07-06  |  9KB  |  366 lines

  1. _PARALLEL C EXTENSIONS_
  2. by Barr E. Bauer
  3.  
  4. [LISTING ONE]
  5.  
  6. /* Loop parallelism sum reduction critical block within loop nest
  7.  * B. E. Bauer 1992 -- compiled using the following on the IRIS:
  8.  *     parallel: cc -O2 -o example1p -mp example1.c
  9.  *     serial: cc -O2 -o example1 example1.c  */
  10. #include <stdio.h>
  11. #define MAX 1536
  12. double a[MAX][MAX], b[MAX][MAX];
  13. main()
  14. {
  15.     int i, j, k, k1;
  16.     double sum=0.0, temp;
  17.     /* shared arrays filled; values not important, just order */
  18.     for (i=0; i<MAX; i++) { 
  19.         for (j=0; j<MAX; j++) {
  20.             a[i][j] = (double)i;
  21.             b[i][j] = (double)j;
  22.         }
  23.     }     
  24.     k1 = 256; /* inner loop delay factor */
  25.     /* start of parallel region */
  26.     #pragma parallel shared(a,b,sum) local(i,j,k,temp) byvalue(k1)
  27.     {
  28.         /* pfor block */
  29.         #pragma pfor iterate(i=0; MAX; 1)
  30.             for (i=0; i<MAX; i++) {
  31.                 for (j=0; j<MAX; j++) {
  32.                     temp = a[i][j]-b[i][j];
  33.                     for (k=0; k<k1; k++) /* lengthen execution time */
  34.                         temp += 0.01;
  35.                     #pragma critical
  36.                     {
  37.                         sum += temp;  /* summation in inner loop */
  38.                     }
  39.                 }
  40.             } 
  41.     }
  42.     printf("\nDone! sum = %24.15f\n", sum);
  43. }
  44.  
  45.  
  46. [LISTING TWO]
  47.  
  48. /* Loop parallelism sum reduction critical block moved into local code
  49.  * B. E. Bauer 1992 -- compiled using the following on the IRIS:
  50.  *     parallel: cc -O2 -o example2p -mp example2.c
  51.  *     serial: cc -O2 -o example2 example2.c  */
  52.  
  53. #include <stdio.h>
  54. #define MAX 1536
  55. double a[MAX][MAX], b[MAX][MAX];
  56. main()
  57. {
  58.     int i, j, k, k1;
  59.     double sum=0.0, temp, st;   /* st = local code subtotal */
  60.     /* shared arrays filled; values not important, just order */
  61.     for (i=0; i<MAX; i++) { 
  62.         for (j=0; j<MAX; j++) {
  63.             a[i][j] = (double)i;
  64.             b[i][j] = (double)j;
  65.         }
  66.     }     
  67.     k1 = 256; /* inner loop delay factor */
  68.     /* start of parallel region */
  69.     #pragma parallel shared(a,b,sum) local(i,j,k,temp,st) byvalue(k1)
  70.     {
  71.         st = 0.0;   /* st initialized in each thread */
  72.         /* pfor block */
  73.         #pragma pfor iterate(i=0; MAX; 1)
  74.             for (i=0; i<MAX; i++) {
  75.                 for (j=0; j<MAX; j++) {
  76.                     temp = a[i][j]-b[i][j];
  77.                     for (k=0; k<k1; k++) /* lengthens execution time */
  78.                         temp += 0.01;
  79.                     st += temp;
  80.                 }
  81.             } 
  82.         /* local code grand summation */
  83.         #pragma critical
  84.         {
  85.             sum += st;
  86.         }
  87.     }
  88.     printf("\nDone! sum = %24.15f\n", sum);
  89. }
  90.  
  91.  
  92. [LISTING THREE]
  93.  
  94. /* Block parallelism, producer-consumer problem
  95.  * B. E. Bauer 1992 -- Taken from "Practical Parallel Programming" pp 214-225
  96.  * (C) 1992 Academic Press, Inc. All Rights Reserved. Used with permission. */
  97.  
  98. #include <stdio.h> 
  99. #define MAXCONSUMERS 3
  100. #define MAXPRODUCTS 10000
  101. #define STOP_TOKEN -1
  102. #define NULL_ITEM (node_t *)NULL 
  103. /* the product is defined here */ 
  104. struct node  
  105.     int productid; 
  106.     struct node *next; 
  107. }; 
  108. typedef struct node node_t;  /* the typedef is convenient */ 
  109. node_t *root = NULL_ITEM;  /* linked list root */ 
  110. int max_depth = 0; 
  111. /* ----- create a new "product" -------------------------------- */ 
  112. node_t *make_product(node_t *item, int prodid) 
  113.     item = (node_t *)malloc(sizeof(node_t)); 
  114.     if (item != NULL_ITEM) { 
  115.         item->productid = prodid;
  116.       item->next = NULL_ITEM; 
  117.     } 
  118.     else  
  119.       printf("problems with production, boss...\n"); 
  120.       return (item); 
  121. /* ----- add a "product" to the end of the list ---------------- */ 
  122. node_t *ship_product(node_t *new) 
  123. {
  124.     int cur_depth = 0;
  125.     node_t *list = root;
  126.  
  127.     if (root == NULL_ITEM) 
  128.         root = new;
  129.     else 
  130.     {
  131.         while (list->next != NULL_ITEM)
  132.         {
  133.             list = list->next;
  134.             cur_depth++;
  135.         }
  136.         cur_depth++;
  137.         list->next = new;
  138.     }
  139.     if (cur_depth > max_depth)
  140.         max_depth = cur_depth;
  141. /* ----- pop the product off the beginning of the list --------- */
  142. node_t *receive_product()
  143. {
  144.     node_t *item = root;
  145.     if (root != NULL_ITEM)
  146.         root = root->next;
  147.     return(item);
  148. }
  149. /* ----- consume the product by freeing its memory ------------- */
  150. void consume_product(node_t *item)
  151. {
  152.     if (item != NULL_ITEM)
  153.         free (item);
  154. }
  155. /* ----- the producer ------------------------------------------ */ 
  156. void producer(int cnt) 
  157.     node_t *temp; 
  158.     int i;
  159.     /* make "products" cnt times (limits simulation) */ 
  160.     for (i=0; i<=cnt; i++)
  161.     { 
  162.         if ((temp = make_product(temp,i)) == NULL_ITEM) 
  163.             break; 
  164.         #pragma critical 
  165.         {
  166.             ship_product(temp); 
  167.         }    
  168.     } 
  169.     /* load on stop tokens */ 
  170.     for (i=0; i<MAXCONSUMERS; i++) 
  171.     { 
  172.         if ((temp = make_product(temp, STOP_TOKEN)) == NULL_ITEM) 
  173.             break; 
  174.         #pragma critical 
  175.         {
  176.             ship_product(temp); 
  177.         }         
  178.     } 
  179.     printf("producer calls it quits\n"); 
  180. /* ----- the consumer (created 3 times) ------------------------ */ 
  181. long consumer(int myid) 
  182.     /* local variables */ 
  183.     int consuming = 1, j;
  184.     long consumed = 0;    /* count of "products" */ 
  185.     node_t *item;
  186.     double temp;
  187.     printf("consumer %d starts the shopping day\n", myid);
  188.     while (consuming)     /* loop until stop token seen */ 
  189.     { 
  190.         for (j=0; j<32000; j++)
  191.             temp *= (double)j;
  192.  
  193.         #pragma critical 
  194.         {
  195.             item = receive_product();
  196.         }
  197.         if (item != NULL_ITEM)
  198.         {
  199.             if (item->productid != STOP_TOKEN) 
  200.             {
  201.                 if (item->productid)
  202.                     ++consumed;
  203.                 printf("consumer %d consuming product %d\n", 
  204.                                                      myid, item->productid);
  205.             }
  206.             else
  207.             {
  208.                 consuming = 0;
  209.                 printf("consumer %d ran out of products\n", myid);
  210.             }
  211.             consume_product(item);
  212.         }
  213.     }
  214.     printf("consumer %d consumed %d products\n", myid, consumed);
  215.     return(consumed); 
  216. main() 
  217.     long total, sum[MAXCONSUMERS]; 
  218.     int i; 
  219.     printf("business starts with %d products\n",MAXPRODUCTS); 
  220.     #pragma parallel shared(sum)
  221.     { 
  222.         #pragma independent 
  223.         {
  224.             producer(MAXPRODUCTS); /* start producer */
  225.         }
  226.         #pragma independent 
  227.         {
  228.             sum[0] = consumer(1);  /* start consumer 1 */ 
  229.         }     
  230.         #pragma independent 
  231.         {
  232.             sum[1] = consumer(2);  /* start consumer 2 */ 
  233.         }     
  234.         #pragma independent 
  235.         {
  236.             sum[2] = consumer(3);  /* start consumer 3 */ 
  237.         }
  238.     } 
  239.     for (i=0, total = 0L; i<MAXCONSUMERS; i++) 
  240.         total += sum[i];  /* sum up the products consumed by each */ 
  241.     printf("business over, %d products exchanged\n", total); 
  242.     printf("maximum products in list = %d\n", max_depth-MAXCONSUMERS);
  243.  
  244.  
  245. Example 1:
  246.  
  247. (a)
  248.  
  249. for (sum=i=0; i<max; i++)
  250.     sum += a[i];
  251.  
  252. (b)
  253.  
  254.  
  255. for (i=1; i<max; i++)
  256.     a[i] = b[i] * a[i-1];
  257.  
  258.  
  259. Example  2:
  260.  
  261. (a)
  262.  
  263. Code Block becomes
  264.  
  265. #pragma parallel
  266. #pragma shared (arrayvar1, arrayvar2..., grandtotal)
  267. #pragma local (index1, index2, subtotal1,...)
  268. #pragma byvalue(shared_constant1,...)
  269. {
  270.     Code Block
  271. }
  272.  
  273. or, the equivalent
  274.  
  275. #pragma parallel shared(list) local(list) byvalue(list)
  276. {
  277.     Code Block
  278. }
  279.  
  280.  
  281. (b)
  282.  
  283. /* strictly local code */
  284. #pragma parallel
  285. #pragma local(i, j)
  286. {
  287.     for (i=sum=0; i<1000; i++)
  288.         sum += i;
  289.     printf("sum = %d\n", sum);
  290. }
  291.  
  292.  
  293. Example 3:
  294.  
  295. for (i=0; i<max; i++)
  296.         b[i] = const*a[i];
  297.  
  298. becomes
  299.  
  300. #pragma parallel shared(a,b) local(i) byvalue(max,const)
  301. {
  302.     #pragma pfor iterate(i=0; max; 1)
  303.         for (i=0; i<max; i++)
  304.             b[i] = const*a[i];
  305. }
  306.  
  307.  
  308.  
  309.  
  310. Example 4:
  311.  
  312.  
  313. code block 1
  314. code block 2
  315.  
  316. becomes
  317.  
  318. #pragma parallel shared(list) local(list) byvalue(list)
  319. {
  320.     #pragma independent
  321.     {
  322.         code block 1
  323.     }
  324.     #pragma independent
  325.     {
  326.         code block 2
  327.     }
  328. }
  329.  
  330.  
  331. Example 5:
  332.  
  333. (a)
  334.  
  335. sum = 0.0;
  336. #pragma parallel shared (sum, a) local(i) byvalue(max)
  337. {
  338.     #pragma pfor iterate (i=0; max; 1)
  339.         for (i=0; i<max; i++)
  340.             sum +=  a[i];
  341. }
  342.  
  343. (b)
  344.  
  345. sum = 0.0;
  346. #pragma parallel shared (sum, a) local(i) byvalue(max)
  347. {
  348.     #pragma pfor iterate (i=0; max; 1)
  349.         for (i=0; i<max; i++)
  350.             #pragma critical
  351.         {
  352.         sum += a[i];
  353.         }
  354. }
  355.  
  356.