parallel processing - Passing variables directly into threaded subroutines -
i have textbook example demonstrates fixing data scoping through parameters. wondering why in code snippet below author uses common block define 2 variables, istart , iend, ** supposed private each thread? not "shared" property of variables common attribute conflict author's intention specify **istart , iend private? or should remove common block?
the author says, "we use common block named bounds containing istart , iend, containing values used in both main program , subroutine." wondering if common attribute inherited calling subroutine of each thread , interfere "private" property istart , iend supposed bear.
lee
program main ... common /bounds/ istart,iend integer :: iarray(10000),n n=10000 ... !$omp parallel private(iam,nthreads,chunk), & !$omp& private(istart,iend) nthreads=omp_get_num_threads() iam = omp_getthread_num() chunk=(n+nthreads-1)/nthreads istart=iam*chunk+1 iend=min((iam+1)*chunk,n) call work(iarray,istart,iend) !$omp end parallel end program main subroutine work(iarray,istart,iend) ... integer :: iarray(10000) i=istart,iend iarray(i)=i*i endddo end subroutine work in other example, author writes following code snippet same purpose. in case, should keep common block in both main , subroutine procedures, right?
program main ... common /bounds/ istart, iend !$omp threadprivate(/bounds/) 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 subroutine work(iarray) ... common /bounds/ istart, iend !$omp threadprivate(/bounds/) integer iarray(10000) = istart, iend iarray(i) = * enddo end subroutine work if pass variables istart , iend in modern manner, correct @ making following revision (which looks little weird me because argument of threadprivate clause not names of common blocks):
program main use model ... !$omp threadprivate(istart,iend) 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 module model integer :: istart,iend contains subroutine work(iarray) ... !$omp threadprivate(istart,iend) integer iarray(10000) = istart, iend iarray(i) = * enddo end subroutine work end module model
if more or less complete example don't see place common block. no actual sharing happens here, because values private each thread in parallel block , passed dummy arguments.
i remove it.
the other case different. here variables shared using common block , privatized using threadprivate. correct usage, although more modern style use module variables same way.
with modules 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) = istart, iend iarray(i) = * enddo end subroutine work end module model program main use parameters !not 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 threadprivate directive used @ declaration of variables used in it.
remark, common not attribute of variable, separate entity containing variables. therefore there no way dummy arguments inherit common.
Comments
Post a Comment