Fortran OpenMP将在哪里分配数组

时间:2012-03-19 14:32:40

标签: arrays stack heap fortran openmp

我对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 )
  • 在第一个代码中,有两个关键区域。我认为,他们会减慢执行速度并且不能很好地扩展。 (我实际上不确定我是否可以将它们排除在外,因为分配是线程保存的?)但是如果数组是在堆栈上分配的,那么它应该更快,因为访问速度更快。
  • 在第二个代码中,我确信堆上有数组,访问速度较慢。但是如果第一个代码中的数组也在堆上分配,那么我将保存关键的reagions +它只有一个分配/解除分配。应该更快?
  • 数组的大小是否会在此处播放?
  • 如果要在堆上分配,是否有办法强制在堆栈上进行分配?

简短的问题基本上是:哪个似乎是问题的最佳解决方案?

2 个答案:

答案 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 - 它更简单,保持私密性好,指针很差,如果内存分配时间是你的限制步骤那么你几乎肯定没有足够的工作平行区域使其平行化是值得的。