Here’s sequential code:
do i = 1, n
do j = i+1, n
if ("some_condition(i,j)") then
result = "here's result"
return
end if
end do
end do
Is there a cleaner way to execute iterations of the outer loop concurrently other than:
!$OMP PARALLEL private(i,j)
!$OMP DO
do i = 1, n
!$OMP FLUSH(found)
if (found) goto 10
do j = i+1, n
if ("some_condition(i,j)") then
!$OMP CRITICAL
!$OMP FLUSH(found)
if (.not.found) then
found = .true.
result = "here's result"
end if
!$OMP FLUSH(found)
!$OMP END CRITICAL
goto 10
end if
end do
10 continue
end do
!$OMP END DO NOWAIT
!$OMP END PARALLEL
The order of iterations over i-loop may be arbitrary as long as some result is found (it doesn’t matter if it changes from run to run as long as it satisfies "some_condition").
It seems
$OMP DOdoesn’t allow break out of the loop earlier. An alternative might be to implement it by hand.Give each thread fixed continuous range of indices to process
Following Guide into OpenMP: Easy multithreading programming for C++:
UPDATE: replaced
gotobyexit, introducedresultsarray based on @M. S. B.’s answer.If solution exists this approach is faster then
$OMP DOdue to earlier exit.Give each thread one iteration at a time to process
Using task directive (suggested by @High Performance Mark):
This variant is 2 times faster on my tests than the version with the
outer-loop.