omp_lastprivate.cpp (1637B)
1 #include <iostream> 2 3 int main(void) 4 { 5 int a = -1; 6 #pragma omp parallel 7 { 8 #pragma omp for lastprivate(a) // private copy of a (uninitialized!) 9 for (int i = 0; i < 100; ++i) { 10 a = i; // no race condition -> `a` is private copy in loop body 11 } 12 #pragma omp single 13 { 14 std::cout << "After consecutive iterations: a = " << a << std::endl; 15 a = -1; 16 } // implicit barrier required here -> otherwise race condition on `a` 17 // below! 18 19 #pragma omp for lastprivate(a) // private copy of a (uninitialized!) 20 for (int i = 0; i < 100; ++i) { 21 // An optimizing compiler will remove this loop completely and let 22 // one thread write to the shared variable a = 66 because the given 23 // lastprivate(a) OpenMP clause will still apply even if the 24 // optimizer phase removes the loop (see for yourself what happens 25 // if you change it to private(a)). 26 // 27 // If the loop was not optimized away, it would be executed in 28 // parallel and the last element 99 in the iteration sequence would 29 // apply to the lastprivate(a) update. Because that thread will 30 // have never written to its private copy, it would result in 31 // undefined behavior because lastprivate(a) like private(a) do not 32 // initialize the private copies! It would be a bug. 33 if (66 == i) { 34 a = i; 35 } 36 } 37 #pragma omp single 38 std::cout << "After non-consecutive iterations: a = " << a << std::endl; 39 } 40 return 0; 41 }