我对Fortran-OpenMP和可分配数组有疑问。这很简单:空间将分配到哪里?如果我有像
这样的东西!$omp parallel default(shared) private(arr)
!$omp critical
allocate( arr(BIGNUMBER) )
!$omp end critical
!do calculations with many arr accesses
!$omp critical
deallocate( arr )
!$omp end critical
!$omp end parallel
是否会在堆栈或堆上分配空间?如果它在堆上,那么上面的代码和类似的东西之间是否存在差异
allocate( arr(BIGNUMBER, nThread) )
!$omp parallel default(shared) private(localArr)
iThread = omp_get_thread_num()
localArr => arr(:, iThread)
!do calculations with many localArr accesses
!$omp end parallel
deallocate( arr )
简短的问题基本上是:哪个似乎是问题的最佳解决方案?
答案 0 :(得分:4)
使用OpenMP的Fortran编译器倾向于在堆栈上分配自动变量(包括数组)。当您进行显式分配时,它们将在堆上分配,但请注意Fortran标准根本不涉及堆栈或堆,它取决于编译器。在前。数字1我会离开关键部分,因为你正在分配私有变量。关于大小,由于自动数组太大,有时会出现堆栈溢出,但这可能不是你的情况。什么是我不知道的最快的方法。
该程序在我的编译器
中分配堆上的数组integer,parameter :: BIGNUMBER = 100000000
real,dimension(:),allocatable :: arr
!$omp parallel default(shared) private(Arr)
allocate( arr(BIGNUMBER) )
iThread = omp_get_thread_num()
arr = 5
print *, arr
deallocate( arr )
!$omp end parallel
end
并且这个在堆栈上(然后崩溃)
integer,parameter :: BIGNUMBER = 100000000
real arr(BIGNUMBER)
!$omp parallel default(shared) private(Arr)
iThread = omp_get_thread_num()
arr = 5
print *, arr
!$omp end parallel
end
答案 1 :(得分:2)
但是......你给人的印象是你认为对堆栈上分配的内存的访问速度比堆上的更快。在任何典型的实现中都不是这种情况 - 访问时间是相同的。堆栈上的内存分配通常比堆上快,但一旦分配,访问它的时间是相同的。因此,我会削减批评并走向路线1 - 它更简单,保持私密性好,指针很差,如果内存分配时间是你的限制步骤那么你几乎肯定没有足够的工作平行区域使其平行化是值得的。