필자가 작성한 코드를 병렬 처리하려고합니다. 배열에 감축을 수행하는 데 문제가 있습니다. 모든 작은 배열에 대해 잘 작동하는 것, 그러나 배열 크기가 특정 지점 위에 갈 때 나는 스택 오버플로 오류 또는 충돌 얻을.Fortran에서 Openmp 배열 축소
컴파일 시간에/F를 사용하여 스택 크기를 늘리려고했는데, Windows에서 ifort를 사용하고 있고, set KMP_STACKSIZE = xxx 인텔 전용 스택 크기 decleration을 전달하려고했습니다. 이것은 때로는 도움이되고 코드가 더 이상 루프를 통해 진행될 수 있지만 결국 스택 크기가 1Gb 이상인 경우에도 문제가 해결되지 않습니다.
다음은 내 코드의 작은 자체 포함 작업 예제입니다. 그것은 연속적으로, 그리고 하나의 스레드와 함께 작동합니다. 또는 많은 스레드가 있지만 작은 'N'이 있습니다. 큰 N (예에서 250,000)은 문제를 일으 킵니다.
이러한 배열이 너무 커서 거대한 문제를 일으키지 않는다고 생각하고 스택 공간을 늘리는 것이 도움이 될 것입니다. 다른 옵션이 있습니까, 아니면 코딩에서 중요한 부분을 놓쳤습니까?
program testreduction
use omp_lib
implicit none
integer :: i, j, nthreads, Nsize
integer iseed /3/
REAL, allocatable :: A(:,:), B(:), C(:), posi(:,:)
REAL :: dx, dy, r, Axi, Ayi, m, F
!Set size of matrix, and main loop
Nsize = 250000
m = 1.0
F = 1.0
!Allocate posi array
allocate(posi(2,Nsize))
!Fill with random numbers
do i=1,Nsize
do j=1,2
posi(j,i) = (ran(iseed))
end do
end do
!Allocate other arrays
allocate(A(2,Nsize), C(Nsize), B(Nsize))
print*, sizeof(A)+sizeof(B)+sizeof(C)
!$OMP parallel
nthreads = omp_get_num_threads()
!$OMP end parallel
print*, "Number of threads ", nthreads
!Go through each array and do some work, calculating a reduction on A, B and C.
!$OMP parallel do schedule(static) private(i, j, dx, dy, r, Axi, Ayi) reduction(+:C, B, A)
do i=1,Nsize
do j=1,Nsize
!print*, i
dx = posi(1,i) - posi(1,j)
dy = posi(2,i) - posi(2,j)
r = sqrt(dx**2+dy**2)
Axi = -m*(F)*(dx/(r))
Ayi = -m*(F)*(dy/(r))
A(1,i) = A(1,i) + Axi
A(2,i) = A(2,i) + Ayi
B(i) = B(i) + (Axi+Ayi)
C(i) = C(i) + dx/(r) + dy/(r)
end do
END DO
!$OMP END parallel do
end program
UPDATE
내가 무슨 말을 좀 더 예 ..
program testreduction2
use omp_lib
implicit none
integer :: i, j, nthreads, Nsize, q, k, nsize2
REAL, allocatable :: A(:,:), B(:), C(:)
integer, ALLOCATABLE :: PAIRI(:), PAIRJ(:)
Nsize = 25
Nsize2 = 19
q=0
allocate(A(2,Nsize), C(Nsize), B(Nsize))
ALLOCATE(PAIRI(nsize*nsize2), PAIRJ(nsize*nsize2))
do i=1,nsize
do j =1,nsize2
q=q+1
PAIRI(q) = i
PAIRJ(q) = j
end do
end do
A = 0
B = 0
C = 0
!$OMP parallel do schedule(static) private(i, j, k)
do k=1,q
i=PAIRI(k)
j=PAIRJ(k)
A(1,i) = A(1,i) + 1
A(2,i) = A(2,i) + 1
B(i) = B(i) + 1
C(i) = C(i) + 1
END DO
!$OMP END parallel do
PRINT*, A
PRINT*, B
PRINT*, C
END PROGRAM
이 예제에서 당신은 정확하지만 나는 실제 코드에서는 감소가 필요하지 않습니다. 이것은 제가 생각할 수있는 가장 단순한 예일뿐입니다. – MechanicalEagle36
업데이트가 줄어들 필요가 없습니다. 다른 것을 가지고 있다면 보여주십시오. –
다른 코드 예제를 추가했습니다. 실제로이 코드 예제를 실제로 보여줍니다. 이 경우, 나는 ** 어떤 일이 발생했는지를 알기 위해 감축을하지 않았습니다 **. 각 배열의 각 요소에 대한 대답은 19 여야합니다. 이상하게도 위의 예에서 실제로 작동하는 것 같습니다. 나는 왜 그런지 잘 모르겠다. 이 예제에서 'i'와 같은 값을 갖는 다른 스레드를 중지시키는 것은 무엇이며 왜이 문제가 발생하지 않습니까? – MechanicalEagle36