В чем разница между (ulimit -s неограничено) и (export KMP_STACKSIZE = xx)? - PullRequest
1 голос
/ 08 марта 2019

Я запустил свою программу, как показано ниже, и использовал (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

Это работает хорошо, но я не знаю разницы между этими двумя командами. В чем разница?

1 Ответ

2 голосов
/ 08 марта 2019

ulimit устанавливает ограничения ОС для программы.

KMP_STACKSIZE сообщает реализации OpenMP о том, сколько стека фактически выделяет для каждого из стеков.Таким образом, в зависимости от настроек вашей ОС по умолчанию вам могут потребоваться оба варианта.Кстати, вам лучше вместо этого использовать OMP_STACKSIZE, поскольку KMP_STACKSIZE - это переменная окружения, используемая компиляторами Intel и Clang.OMP_STACKSIZE - это стандартный способ установки размера стека потоков OpenMP.

Обратите внимание, что эта проблема обычно более уязвима, поскольку Fortran стремится хранить больше данных в стеке, особенномассивы.Некоторые компиляторы могут автоматически перемещать такие массивы в кучу, см., Например, -heap-arrays для компилятора Intel.

...