Fortran OpenMP 数组将分配在哪里

Cab*_*ath 3 arrays fortran heap-memory openmp stack-memory

我有一个关于 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
Run Code Online (Sandbox Code Playgroud)

空间是分配在栈上还是堆上?如果它在堆上,上面的代码和类似的代码之间有区别吗

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

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

Vla*_*r F 6

使用 OpenMP 的 Fortran 编译器倾向于在堆栈上分配自动变量(包括数组)。当你进行显式分配时,它们将在堆上分配,但请注意,Fortran 标准根本不谈论堆栈或堆,这取决于编译器。在前。第 1 我会忽略关键部分,因为您正在分配私有变量。关于大小,有时会由于自动数组太大而导致堆栈溢出,但这可能不是您的情况。我不知道最快的方法是什么。

该程序在我的编译器中的堆上分配数组

integer,parameter :: BIGNUMBER = 100000000
real,dimension(:),allocatable :: arr

allocate( arr(BIGNUMBER) )

!$omp parallel default(shared) private(Arr)
  iThread = omp_get_thread_num()

  arr = 5
  
  print *, arr

!$omp end parallel
deallocate( arr )


end
Run Code Online (Sandbox Code Playgroud)

和这个在堆栈上(然后它崩溃了)

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
Run Code Online (Sandbox Code Playgroud)