回 帖 发 新 帖 刷新版面

主题:ivf openmp 并行 堆栈溢出

我在写一个openmp的并行程序,当程序数组比较大时,就会出现堆栈溢出错误。
网上说增加堆栈大小,这个方法可行吗?计算时都是什么变量要进入堆栈?

回复列表 (共15个回复)

沙发

要看是OMP的线程堆栈还是程序堆栈. windows下在IDE里设置程序的堆栈. 如果是OMP线程堆栈在官方文档里面介绍是通过环境变量来设置的. 如果你的程序没错, 那很可能就是堆栈溢出而已, 修改一下堆栈大小应该就没问题了.
具体那些变量放入栈里面我没研究过.

板凳

增加堆栈的大小可以,但在Windows下,一般堆栈最大只能有128M,不知道能不能满足你程序的要求。OpenMP中的大数组很容易堆栈溢出。在调用子程序的时候,除了子程序中药用到的全局变量外,其它的数据和程序代码都是要进堆栈的。所以比如有4个线程在并行,调用子程序的时候要进堆栈的东西就多了3倍,如果有大数组,特别容易溢出。
解决的方法就是增大堆栈,这个是没有问题的。如果堆栈大了还不行,就考虑把你的大数组在子程序中设为假定形状大小数组,假定形状大小数组不进堆栈,就不会溢出了。

3 楼

[quote]增加堆栈的大小可以,但在Windows下,一般堆栈最大只能有128M,不知道能不能满足你程序的要求。OpenMP中的大数组很容易堆栈溢出。在调用子程序的时候,除了子程序中药用到的全局变量外,其它的数据和程序代码都是要进堆栈的。所以比如有4个线程在并行,调用子程序的时候要进堆栈的东西就多了3倍,如果有大数组,特别容易溢出。
解决的方法就是增大堆栈,这个是没有问题的。如果堆栈大了还不行,就考虑把你的大数组在子程序中设为假定形状大小数组,假定形状大小数组不进堆栈,就不会溢出了。[/quote]

确切的说不进stack(栈)了

4 楼


请问什么是假定形状大小数组?指的是allocate 吗?

我试了一下,把下面程序的数组IC设置成allocatable就没问题,直接定义为 dimension IC(NMAX) 就会提示栈溢出

       PROGRAM HELLO
       CHARACTER*80 fname1
       REAL(4) s
       integer, allocatable, dimension (:) :: IC       
       PARAMETER (NMAX = 100000000)
       ALLOCATE ( IC(NMAX))

!$OMP PARALLEL PRIVATE(I),SHARED(IC)
!$OMP DO SCHEDULE(DYNAMIC)
        DO I = 1, NMAX
             IC(I) = I*3
        END DO
!$OMP END DO
        write (*,*) "I = " ,IC(100)

!$OMP END PARALLEL 

       END

5 楼

4楼的代码当然不会有问题啦,因为Allocate出来的东东是在堆上,跟栈基本没关了。

6 楼


我是小白,对堆和栈不怎么懂

我对openmp的理解是只有私有变量(private)是要进栈的,共享变量(shared)使用的还是静态内存,不知道对不对。

如果是这样的话IC数组设置的是共享变量怎么会栈溢出呢?

7 楼

楼上理解不完全正确,这种理解只是在部分情况下OK而已~~~~~

8 楼

private私有变量 是会在各个线程分别产生一份的, shared公有一般就是原变量地址不变. 我也觉得局部那样理解或者是可以的.

9 楼

在这种情况下数组IC是不进栈的,
那么怎么栈溢出呢?

      PROGRAM HELLO
      DIMENSION IC (10000000)

!$OMP PARALLEL PRIVATE(I),SHARED(IC)
!$OMP DO SCHEDULE(DYNAMIC)
        DO I = 1, NMAX
             IC(I) = I*3
        END DO
!$OMP END DO
        write (*,*) "I = " ,IC(100)

!$OMP END PARALLEL 

       END

10 楼

所以我说不完全正确。
一般编译器会将静态变量区与栈区放在一个段里。

我来回复

您尚未登录,请登录后再回复。点此登录或注册