fork download
  1. // LICENSE : GPL 3, see file LICENSE_GPL-3.txt
  2.  
  3. #include <stdlib.h>
  4. #include <stdio.h>
  5. #include <omp.h>
  6.  
  7. #ifndef N
  8. #define N 5
  9. #endif
  10. #ifndef FS
  11. #define FS 37
  12. #endif
  13. #define MULTCOUNT 10000000
  14.  
  15. // The goal of this lab is to demonstrate that unbounded loops such as while
  16. // loops can be parallelized with the omp task clause
  17. // There is overhead associated with omp task scheduler and so it is better for
  18. // performance for each thread to have significant amount of calculation to perform
  19. // relative to the overhead of having a mastrer thread running thru the while loop
  20. // assigning threads
  21. //
  22. // By varying the #define parameters FS & N
  23. // we can vary the amount of computation each thread performs
  24.  
  25. // under the covers, process_work() calculates fibonacci numbers
  26. // fibonacci was chosen because the amount of time it takes to compute fib(38)
  27. // is orders of magintude higher than the time is takes to compute fib(3) for example
  28.  
  29. // this allows us to simply change a few parameters and quickly see the effect of
  30. // omp task scheduling for the linked list exmaple
  31.  
  32. // small values of FS mean we are computing small fib numbers and this takes little time
  33. // small values of N mean we are comuting fewer in a sequence of fib numbers
  34. // this also means that process_work() takes little time
  35. // small values such as FS=3, N=2 take so little time to compute, that the
  36. // overhead of omp task scheduling dominates the execution time
  37. // so the parallel version runs slower
  38. //
  39. // larger values for FS & N means that each thread is doing signicicant work
  40. // and the cost of the omp task scheduler if not as significant
  41. // in such cases, the parallel version of the code runs several times faster
  42. // than the serial version
  43.  
  44. // to experiment with this overhead, modify the values for FS & N
  45.  
  46.  
  47. struct node {
  48. int data;
  49. int fibdata;
  50. struct node* next;
  51. };
  52.  
  53.  
  54. struct node* init_list(struct node* p);
  55. void processwork(struct node* p);
  56. int fib(int n);
  57.  
  58. int fib(int n)
  59. {
  60. int x, y;
  61. if (n < 2) {
  62. return (n);
  63. } else {
  64. x = fib(n - 1);
  65. y = fib(n - 2);
  66. return (x + y);
  67. }
  68. }
  69.  
  70.  
  71. int fibiter(int n)
  72. {
  73. int u = 0;
  74. int v = 1;
  75. int i, t;
  76. int j;
  77.  
  78.  
  79. for (j=0;j<MULTCOUNT;j++) {
  80. u=0;
  81. v=1;
  82. for(i = 2; i <= n; i++)
  83. {
  84. t = u + v;
  85. u = v;
  86. v = t;
  87. }
  88. }
  89. return v;
  90. }
  91.  
  92. void processwork(struct node* p)
  93. {
  94. int n;
  95. n = p->data;
  96. p->fibdata = fib(n);
  97. }
  98.  
  99.  
  100. struct node* init_list(struct node* p) {
  101. int i;
  102. struct node* head = NULL;
  103. struct node* temp = NULL;
  104.  
  105. head = malloc(sizeof(struct node));
  106. p = head;
  107. p->data = FS;
  108. p->fibdata = 0;
  109. for (i=0; i< N; i++) {
  110. temp = malloc(sizeof(struct node));
  111. p->next = temp;
  112. p = temp;
  113. p->data = FS + i + 1;
  114. p->fibdata = i+1;
  115. }
  116. p->next = NULL;
  117. return head;
  118. }
  119.  
  120.  
  121. int main(int argc, char *argv[]) {
  122. struct node *q=NULL;
  123. struct node *temp=NULL;
  124. struct node *head=NULL;
  125. struct node *p;
  126. int threads = 2; //assume 2 threads by default
  127.  
  128.  
  129. printf("Process linked list\n");
  130.  
  131. if (argc >1) {
  132. threads = atoi(argv[1]); // 1st input parameter: number of threads
  133. }
  134.  
  135. printf("Number of threads to use: %d\n",threads);
  136.  
  137. q = init_list(q);
  138. head = q;
  139. p=head;
  140.  
  141. omp_set_num_threads(threads);
  142. #pragma omp parallel
  143. {
  144. #pragma omp single nowait
  145. {
  146. while (p != NULL) {
  147. #pragma omp task firstprivate(p)
  148. {
  149. processwork(p);
  150. }
  151. p = p->next;
  152. }
  153. }
  154. }
  155.  
  156. q = head; //print the resulting computations as a validation check
  157. while (q != NULL) {
  158. printf("%d : %d\n",q->data, q->fibdata);
  159. temp = q->next;
  160. free (q);
  161. q = temp;
  162. }
  163. free (q);
  164.  
  165. return 0;
  166. }
  167.  
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.c: In function ‘main’:
prog.c:142:0: warning: ignoring #pragma omp parallel [-Wunknown-pragmas]
      #pragma omp parallel
 
prog.c:144:0: warning: ignoring #pragma omp single [-Wunknown-pragmas]
        #pragma omp single nowait
 
prog.c:147:0: warning: ignoring #pragma omp task [-Wunknown-pragmas]
          #pragma omp task firstprivate(p)
 
/home/lf7UBw/ccBxbNp3.o: In function `main':
prog.c:(.text.startup+0x4f): undefined reference to `omp_set_num_threads'
collect2: error: ld returned 1 exit status
stdout
Standard output is empty