小编drl*_*mon的帖子

OpenMP:堆数组性能不佳(堆栈数组工作正常)

我是一个相当有经验的OpenMP用户,但我遇到了一个令人费解的问题,我希望有人可以提供帮助.问题是,一个简单的哈希算法对堆栈分配的数组表现良好,但对堆上的数组表现不佳.

下面的示例使用i%M(i模数M)来计算相应阵列元素中的每个第M个整数.为简单起见,假设N = 1000000,M = 10.如果N%M == 0,那么结果应该是bins []的每个元素都等于N/M:

#pragma omp for
  for (int i=0; i<N; i++) 
    bins[ i%M ]++;
Run Code Online (Sandbox Code Playgroud)

数组bins []对每个线程都是私有的(我在之后对关键部分中所有线程的结果进行求和).

当在堆栈上分配bins []时,程序运行良好,性能与内核数量成比例缩放.

但是,如果bin []在堆上(指向bin []的指针在堆栈上),性能会急剧下降.这是一个重大问题!

我希望使用OpenMP将某些数据的binning(散列)并行化为堆数组,这是一个重大的性能影响.

绝对不是像所有线程试图写入同一内​​存区域那样愚蠢的东西.这是因为每个线程都有自己的bins []数组,结果对于堆栈和堆栈分配的bin都是正确的,并且单线程运行的性能没有差别.我使用GCC和英特尔C++编译器在不同的硬件(Intel Xeon和AMD Opteron)上重现了这个问题.所有测试都在Linux(Ubuntu和RedHat)上进行.

似乎没有理由将OpenMP的良好性能限制在堆栈数组中.

任何猜测?也许对线程的访问是通过Linux上的某种共享网关进行的?我该如何解决这个问题?

完整的程序如下:

#include <stdlib.h>
#include <stdio.h>
#include <omp.h>

int main(const int argc, const char* argv[])
{
  const int N=1024*1024*1024;
  const int M=4;
  double t1, t2;
  int checksum=0;

  printf("OpenMP threads: %d\n", omp_get_max_threads());

  //////////////////////////////////////////////////////////////////
  // Case 1: stack-allocated array
  t1=omp_get_wtime();
  checksum=0;
#pragma omp parallel
  { // Each openmp thread …
Run Code Online (Sandbox Code Playgroud)

heap performance stack multithreading openmp

20
推荐指数
1
解决办法
6275
查看次数

Fortran中的可变大小数组,没有Allocate()

有没有办法在堆栈中的Fortran中创建可变大小的数组?Allocate()对我不起作用,因为它将数组放在堆上.这可能会导致并行化问题(请参阅我的另一个问题: OpenMP:堆数组性能不佳(堆栈数组工作正常)).当然,一些智能内存管理会解决这个问题,但Fortran中的内存管理听起来很愚蠢.

基本上,我在C中寻找与以下相同的Fortran:

scanf("%d", N);
int myarray[N];
Run Code Online (Sandbox Code Playgroud)

重新迭代:我不想要

Integer, PARAMETER :: N=100
Integer, Dimension(N) :: myarray
Run Code Online (Sandbox Code Playgroud)

因为这决定了编译时的数组大小.我也不想要

Integer, Dimension(:), Allocatable :: myarray
read(*,*) N
Allocate(myarray(1:N))
Run Code Online (Sandbox Code Playgroud)

因为它将数组放在堆上.

非常感谢帮助.在我最近遇到上述问题中的问题之前,我对Allocatable阵列非常满意.如果对这个问题有一个否定的答案,我非常感谢与该来源的链接.

编辑:查看对MSB答案的评论.这样做的优雅方式只有在Fortran 2008中才有可能实现,并且它是在一个block构造中完成的.

memory arrays heap stack fortran

12
推荐指数
2
解决办法
2万
查看次数

Fortran查询和打印输出函数或子例程名称

在Fortran中是否可以查询我所在的函数或子例程的名称?即,我应该代替'???' 让它在屏幕上打印'my_subroutine'?

subroutine my_subroutine()
   write(*,*) ???
end subroutine my_subroutine
Run Code Online (Sandbox Code Playgroud)

我试图找到一种方法来实现自定义调试器/分析器,只使用文本编辑器的搜索和替换机制.以编程方式查询我在代码中的位置会很有帮助.

debugging profiling fortran

9
推荐指数
2
解决办法
2008
查看次数

Fortran元素函数与元素子例程

Fortan允许元素子例程具有intent(inout)和intent(out)参数,但元素函数仅允许intent(in).

这是为什么?它只是一种风格约定,还是在调用函数和调用子例程方面有一些不同之处?

换一种说法,

Elemental Integer Function FOO(i)
  Integer, intent(in) :: i
    ...
  FOO=something
End Function
Run Code Online (Sandbox Code Playgroud)

Elemental Subroutine FOO(i, v)
  Integer, intent(in)  :: i
  Integer, intent(out) :: v
    ...
  v=something
End Subroutine
Run Code Online (Sandbox Code Playgroud)

- 这些FOO的实现是否等效?

parallel-processing performance multithreading fortran fortran90

8
推荐指数
1
解决办法
2243
查看次数