(ulimit -s unlimited) 和 (export KMP_STACKSIZE = xx) 有什么区别?
what is difference between (ulimit -s unlimited) and (export KMP_STACKSIZE = xx)?
我 运行 我的程序如下所示,并使用了 ( ulimit -s unlimited
)。
有效。
REAL(DP), DIMENSION(1024,2,1541) :: L_X TanV
REAL(DP), DIMENSION(4) :: Val_X, Val_Y
REAL(DP), dimension(1029) :: E_x
REAL(DP), dimension(1024) :: E_y
REAL(DP), DIMENSION(1024,1024) :: E_Fx, E_Fy
!$OMP SECTIONS PRIVATE(i, j, ii,jj, PSL_X, i_x, i_y, Val_X, Val_Y)
!$OMP SECTION
do j=1,LinkPlusBndry
do i=1,Kmax(j)-1
PSL_X(1)=modulo(L_X(i,1,j),H*N2); PSL_X(2)=L_X(i,2,j)
i_x=floor(PSL_X(1)/H)+2; i_y=floor(PSL_X(2)/H)
call Delta4((E_x(i_x:i_x+3)-PSL_X(1))/H,Val_X)
call Delta4((E_y(i_y:i_y+3)-PSL_X(2))/H,Val_Y)
do ii=1,4; do jj=1,4
EE_Fx(i_y+ii-1,i_x+jj-1)=EE_Fx(i_y+ii-1,i_x+jj-1) &
+tauH2*TanV(i,1,j)*Val_X(jj)*Val_Y(ii)
end do; end do
end do
end do
...
...
...
!$OMP SECTION
do j=1,LinkPlusBndry
do i=1,Kmax(j)-1
PSL_X(1)=modulo(L_X(i,1,j),H*N2); PSL_X(2)=L_X(i,2,j)
i_x=floor(PSL_X(1)/H)+2; i_y=floor(PSL_X(2)/H)
call Delta4((E_x(i_x:i_x+3)-PSL_X(1))/H,Val_X)
call Delta4((E_y(i_y:i_y+3)-PSL_X(2))/H,Val_Y)
do ii=1,4; do jj=1,4
EE_Fy(i_y+ii-1,i_x+jj-1)=EE_Fy(i_y+ii-1,i_x+jj-1) &
+tauH2*TanV(i,2,j)*Val_X(jj)*Val_Y(ii)
end do; end do
end do
end do
!$OMP END SECTIONS
我不喜欢使用!$OMP SECTION
,它只使用2个线程来限制速度。
所以我像下面这样更改了我的代码。
!$OMP DO PRIVATE(j, i, PSL_X, i_x, i_y, ii, jj, Val_X, Val_Y) REDUCTION(+:EE_Fx, EE_Fy)
do j=1,LinkPlusBndry
do i=1,Kmax(j)-1
PSL_X(1)=modulo(L_X(i,1,j),H*N2); PSL_X(2)=L_X(i,2,j)
i_x=floor(PSL_X(1)/H)+2; i_y=floor(PSL_X(2)/H)
call Delta4((E_x(i_x:i_x+3)-PSL_X(1))/H,Val_X)
call Delta4((E_y(i_y:i_y+3)-PSL_X(2))/H,Val_Y)
do ii=1,4; do jj=1,4
EE_Fx(i_y+ii-1,i_x+jj-1)=EE_Fx(i_y+ii-1,i_x+jj-1) &
+tauH2*TanV(i,1,j)*Val_X(jj)*Val_Y(ii)
EE_Fy(i_y+ii-1,i_x+jj-1)=EE_Fy(i_y+ii-1,i_x+jj-1) &
+tauH2*TanV(i,2,j)*Val_X(jj)*Val_Y(ii)
end do; end do
PSL_X(1)=modulo(L_X(i+1,1,j),H*N2); PSL_X(2)=L_X(i+1,2,j)
i_x=floor(PSL_X(1)/H)+2; i_y=floor(PSL_X(2)/H)
call Delta4((E_x(i_x:i_x+3)-PSL_X(1))/H,Val_X)
call Delta4((E_y(i_y:i_y+3)-PSL_X(2))/H,Val_Y)
do ii=1,4; do jj=1,4
EE_Fx(i_y+ii-1,i_x+jj-1)=EE_Fx(i_y+ii-1,i_x+jj-1) &
-tauH2*TanV(i,1,j)*Val_X(jj)*Val_Y(ii)
EE_Fy(i_y+ii-1,i_x+jj-1)=EE_Fy(i_y+ii-1,i_x+jj-1) &
-tauH2*TanV(i,2,j)*Val_X(jj)*Val_Y(ii)
end do; end do
end do
end do
!$OMP END DO
当我启动这段代码时,出现分段错误。
我以为是跟内存大小有关。
所以,在搜索之后我找到了这个解决方案
export KMP_STACKSIZE=value
现在我使用 2 个不同的命令
ulimit -s unlimited
和
export KMP_STACKSIZE=value
它运行良好,但我不知道这两个命令之间的区别。
有什么区别?
ulimit
设置程序的 OS 限制。
KMP_STACKSIZE
告诉 OpenMP 实现关于 实际上 为每个堆栈分配多少堆栈。因此,根据您的 OS 默认值,您可能需要两者。顺便说一句,您应该改用 OMP_STACKSIZE
,因为 KMP_STACKSIZE
是 Intel 和 clang 编译器使用的环境变量。 OMP_STACKSIZE
是设置 OpenMP 线程堆栈大小的标准方法。
请注意,这个问题通常更容易暴露,因为 Fortran 倾向于在堆栈上保留更多数据,尤其是。阵列。一些编译器可以自动将这样的数组移动到堆中,例如 -heap-arrays
英特尔编译器。
我 运行 我的程序如下所示,并使用了 ( ulimit -s unlimited
)。
有效。
REAL(DP), DIMENSION(1024,2,1541) :: L_X TanV
REAL(DP), DIMENSION(4) :: Val_X, Val_Y
REAL(DP), dimension(1029) :: E_x
REAL(DP), dimension(1024) :: E_y
REAL(DP), DIMENSION(1024,1024) :: E_Fx, E_Fy
!$OMP SECTIONS PRIVATE(i, j, ii,jj, PSL_X, i_x, i_y, Val_X, Val_Y)
!$OMP SECTION
do j=1,LinkPlusBndry
do i=1,Kmax(j)-1
PSL_X(1)=modulo(L_X(i,1,j),H*N2); PSL_X(2)=L_X(i,2,j)
i_x=floor(PSL_X(1)/H)+2; i_y=floor(PSL_X(2)/H)
call Delta4((E_x(i_x:i_x+3)-PSL_X(1))/H,Val_X)
call Delta4((E_y(i_y:i_y+3)-PSL_X(2))/H,Val_Y)
do ii=1,4; do jj=1,4
EE_Fx(i_y+ii-1,i_x+jj-1)=EE_Fx(i_y+ii-1,i_x+jj-1) &
+tauH2*TanV(i,1,j)*Val_X(jj)*Val_Y(ii)
end do; end do
end do
end do
...
...
...
!$OMP SECTION
do j=1,LinkPlusBndry
do i=1,Kmax(j)-1
PSL_X(1)=modulo(L_X(i,1,j),H*N2); PSL_X(2)=L_X(i,2,j)
i_x=floor(PSL_X(1)/H)+2; i_y=floor(PSL_X(2)/H)
call Delta4((E_x(i_x:i_x+3)-PSL_X(1))/H,Val_X)
call Delta4((E_y(i_y:i_y+3)-PSL_X(2))/H,Val_Y)
do ii=1,4; do jj=1,4
EE_Fy(i_y+ii-1,i_x+jj-1)=EE_Fy(i_y+ii-1,i_x+jj-1) &
+tauH2*TanV(i,2,j)*Val_X(jj)*Val_Y(ii)
end do; end do
end do
end do
!$OMP END SECTIONS
我不喜欢使用!$OMP SECTION
,它只使用2个线程来限制速度。
所以我像下面这样更改了我的代码。
!$OMP DO PRIVATE(j, i, PSL_X, i_x, i_y, ii, jj, Val_X, Val_Y) REDUCTION(+:EE_Fx, EE_Fy)
do j=1,LinkPlusBndry
do i=1,Kmax(j)-1
PSL_X(1)=modulo(L_X(i,1,j),H*N2); PSL_X(2)=L_X(i,2,j)
i_x=floor(PSL_X(1)/H)+2; i_y=floor(PSL_X(2)/H)
call Delta4((E_x(i_x:i_x+3)-PSL_X(1))/H,Val_X)
call Delta4((E_y(i_y:i_y+3)-PSL_X(2))/H,Val_Y)
do ii=1,4; do jj=1,4
EE_Fx(i_y+ii-1,i_x+jj-1)=EE_Fx(i_y+ii-1,i_x+jj-1) &
+tauH2*TanV(i,1,j)*Val_X(jj)*Val_Y(ii)
EE_Fy(i_y+ii-1,i_x+jj-1)=EE_Fy(i_y+ii-1,i_x+jj-1) &
+tauH2*TanV(i,2,j)*Val_X(jj)*Val_Y(ii)
end do; end do
PSL_X(1)=modulo(L_X(i+1,1,j),H*N2); PSL_X(2)=L_X(i+1,2,j)
i_x=floor(PSL_X(1)/H)+2; i_y=floor(PSL_X(2)/H)
call Delta4((E_x(i_x:i_x+3)-PSL_X(1))/H,Val_X)
call Delta4((E_y(i_y:i_y+3)-PSL_X(2))/H,Val_Y)
do ii=1,4; do jj=1,4
EE_Fx(i_y+ii-1,i_x+jj-1)=EE_Fx(i_y+ii-1,i_x+jj-1) &
-tauH2*TanV(i,1,j)*Val_X(jj)*Val_Y(ii)
EE_Fy(i_y+ii-1,i_x+jj-1)=EE_Fy(i_y+ii-1,i_x+jj-1) &
-tauH2*TanV(i,2,j)*Val_X(jj)*Val_Y(ii)
end do; end do
end do
end do
!$OMP END DO
当我启动这段代码时,出现分段错误。
我以为是跟内存大小有关。 所以,在搜索之后我找到了这个解决方案
export KMP_STACKSIZE=value
现在我使用 2 个不同的命令
ulimit -s unlimited
和
export KMP_STACKSIZE=value
它运行良好,但我不知道这两个命令之间的区别。 有什么区别?
ulimit
设置程序的 OS 限制。
KMP_STACKSIZE
告诉 OpenMP 实现关于 实际上 为每个堆栈分配多少堆栈。因此,根据您的 OS 默认值,您可能需要两者。顺便说一句,您应该改用 OMP_STACKSIZE
,因为 KMP_STACKSIZE
是 Intel 和 clang 编译器使用的环境变量。 OMP_STACKSIZE
是设置 OpenMP 线程堆栈大小的标准方法。
请注意,这个问题通常更容易暴露,因为 Fortran 倾向于在堆栈上保留更多数据,尤其是。阵列。一些编译器可以自动将这样的数组移动到堆中,例如 -heap-arrays
英特尔编译器。