Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>There's no problem with having the parallel section start in another routine before the for, certainly since OpenMP 3.0 (2008) and maybe since OpenMP 2.5. With gcc4.4:</p> <p>outer.c:</p> <pre><code>#include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; #include &lt;omp.h&gt; void update(int n, int iter); int main(int argc, char **argv) { int n=10; #pragma omp parallel num_threads(4) default(none) shared(n) for (int iter=0; iter&lt;3; iter++) { #pragma omp single printf("---iteration %d---\n", iter); update(n, iter); } return 0; } </code></pre> <p>inner.c:</p> <pre><code>#include &lt;omp.h&gt; #include &lt;stdio.h&gt; void update(int n, int iter) { int thread = omp_get_thread_num(); #pragma omp for for (int i=0;i&lt;n;i++) { int newthread=omp_get_thread_num(); printf("%3d: doing loop index %d.\n",newthread,i); } } </code></pre> <p>Building:</p> <pre><code>$ make gcc44 -g -fopenmp -std=c99 -c -o inner.o inner.c gcc44 -g -fopenmp -std=c99 -c -o outer.o outer.c gcc44 -o main outer.o inner.o -fopenmp -lgomp $ ./main ---iteration 0--- 2: doing loop index 6. 2: doing loop index 7. 2: doing loop index 8. 0: doing loop index 0. 0: doing loop index 1. 0: doing loop index 2. 1: doing loop index 3. 1: doing loop index 4. 1: doing loop index 5. 3: doing loop index 9. ---iteration 1--- 0: doing loop index 0. 0: doing loop index 1. 0: doing loop index 2. 1: doing loop index 3. 1: doing loop index 4. 1: doing loop index 5. 3: doing loop index 9. 2: doing loop index 6. 2: doing loop index 7. 2: doing loop index 8. ---iteration 2--- 0: doing loop index 0. 0: doing loop index 1. 0: doing loop index 2. 3: doing loop index 9. 2: doing loop index 6. 2: doing loop index 7. 2: doing loop index 8. 1: doing loop index 3. 1: doing loop index 4. 1: doing loop index 5. </code></pre> <p>But as per @jdv-Jan de Vaan, I'd be very surprised if in a up-to-date OpenMP implmentation this led to a significant performance improvement over having the parallel for in update, particularly if update is expensive enough. </p> <p>BTW, there are issues with just putting a parallel for around the i-loop in the Gauss-Seidel routine in update; you can see that the i steps aren't independant, and that will lead to race conditions. You will need to do something like Red-Black or Jacobi iteration instead... </p> <p><strong>Update:</strong></p> <p>The code sample provided is for a G-S iteration, not Jacobi, but I'll just assume that's a typo.</p> <p>If your question is actually about the reduce and not the orphaned for loop: yes, you sadly have to roll your own min/max reductions in OpenMP, but it's pretty straightforward, you just use the usual tricks.</p> <p><strong>Update 2</strong> -- yikes, locmax needs to be private, not shared.</p> <p>outer.c:</p> <pre><code>#include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; #include &lt;omp.h&gt; int update(int n, int iter); int main(int argc, char **argv) { int n=10; int max, locmax; max = -999; #pragma omp parallel num_threads(4) default(none) shared(n, max) private(locmax) for (int iter=0; iter&lt;3; iter++) { #pragma omp single printf("---iteration %d---\n", iter); locmax = update(n, iter); #pragma omp critical { if (locmax &gt; max) max=locmax; } #pragma omp barrier #pragma omp flush #pragma omp single printf("---iteration %d's max value = %d---\n", iter, max); } return 0; } </code></pre> <p>inner.c:</p> <pre><code>#include &lt;omp.h&gt; #include &lt;stdio.h&gt; int update(int n, int iter) { int thread = omp_get_thread_num(); int max = -999; #pragma omp for for (int i=0;i&lt;n;i++) { printf("%3d: doing loop index %d.\n",thread,i); if (i+iter&gt;max) max = i+iter; } return max; } </code></pre> <p>and building:</p> <pre><code>$ make gcc44 -g -fopenmp -std=c99 -c -o inner.o inner.c gcc44 -g -fopenmp -std=c99 -c -o outer.o outer.c gcc44 -o main outer.o inner.o -fopenmp -lgomp bash-3.2$ ./main ---iteration 0--- 0: doing loop index 0. 0: doing loop index 1. 0: doing loop index 2. 2: doing loop index 6. 2: doing loop index 7. 2: doing loop index 8. 1: doing loop index 3. 1: doing loop index 4. 1: doing loop index 5. 3: doing loop index 9. ---iteration 0's max value = 9--- ---iteration 1--- 0: doing loop index 0. 0: doing loop index 1. 0: doing loop index 2. 3: doing loop index 9. 2: doing loop index 6. 2: doing loop index 7. 2: doing loop index 8. 1: doing loop index 3. 1: doing loop index 4. 1: doing loop index 5. ---iteration 1's max value = 10--- ---iteration 2--- 0: doing loop index 0. 0: doing loop index 1. 0: doing loop index 2. 1: doing loop index 3. 1: doing loop index 4. 1: doing loop index 5. 3: doing loop index 9. 2: doing loop index 6. 2: doing loop index 7. 2: doing loop index 8. ---iteration 2's max value = 11--- </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload