首页 > 解决方案 > 为什么在添加存储在数组中的数字时在 Openmp 中出现分段错误?

问题描述

我是 Openmp 的新手。我正在总结存储在数组中的 N 个整数并使用 gfortran 编译代码。直到 N=10^6,串行和并行代码得到的结果完全相同。对于 N=10^7,串行代码正在运行,但并行代码(使用 -fopenmp 标志编译后)给出“分段错误”。我在这里给出了我的代码。谁能帮助我为什么会这样?

  use omp_lib
  REAL*8 r,summ,sl
  parameter (N=10000000)
  dimension r(N)

  do i=1,N
  r(i)=i
  enddo

  summ=0.0d00
  sl=0.0d00

  !$OMP PARALLEL FIRSTPRIVATE(sl) SHARED(r,summ)
  !$OMP DO 
  do i=1,N
  sl=sl+r(i)
  enddo
  !$OMP END DO
  !$OMP CRITICAL
  summ=summ+sl
  !$OMP END CRITICAL
  !$OMP END PARALLEL

  write(*,*)'SUM',summ

  end

标签: parallel-processingfortranopenmpgfortran

解决方案


我以前遇到过同样的问题。问题是您的代码似乎需要大内存。

确保在编译代码时使用编译器选项-mcmodel=medium。此外,当您-fopenmp系统地使用编译器调用时-frecursive,会将堆栈的大小限制为默认值。因此,您的代码尝试在导致分段错误的堆栈限制之外写入。要摆脱这个问题,您必须取消堆栈的默认限制。一种快速执行此操作的方法是在终端上运行命令ulimit -s unlimited,然后在同一终端中启动您的代码。您还可以使用-fmax-stack-var-size=n具有良好 n 值的编译选项来设置堆栈的大小,使其适合您的数据。

另外,我建议使用reduction (+:sum)子句来计算总和,而不是声明在这种情况下效率低且可避免的临界区域。

我希望这对你有帮助。


推荐阅读