If this more or less the complete example I don't see any place for the common block. No actual sharing happens here, because the values are private to each thread in the parallel
block and they are passed as dummy arguments.
I would really remove it.
The other case is different. Here the variables are shared using the common block and privatized using threadprivate
. This is a correct usage, although more modern style is to use module variables the same way.
With modules I would do:
module parameters
integer :: istart,iend
!$omp threadprivate(istart,iend)
end module
module model
use parameters
implicit none
contains
subroutine work(iarray)
...
integer iarray(10000)
do i = istart, iend
iarray(i) = i * i
enddo
end subroutine work
end module model
program main
use parameters !not completely necessary here
use model
implicit none
...
integer iarray(10000)
N = 10000
!$omp parallel private(iam, nthreads, chunk)
nthreads = omp_get_num_threads()
iam = omp_get_thread_num()
chunk = (N + nthreads – 1)/nthreads
istart = iam * chunk + 1
iend = min((iam + 1) * chunk, N)
call work(iarray)
!$omp end parallel
end program main
Notice the threadprivate
directive is used only at the declaration of the variables used in it.
Remark, common
is not an attribute of a variable, it is a separate entity containing the variables. Therefore there is no way the dummy arguments could inherit common
.