У меня возникли проблемы при выполнении программы с параллельным выполнением.Вот тестовый код.
module test
use, intrinsic :: iso_fortran_env, only: dp => real64
implicit none
contains
subroutine Addition(x,y,s)
real(dp),intent(in) :: x,y
real(dp), intent(out) :: s
s = x+y
end subroutine Addition
function linspace(length,xi,xf) result (vec)
! function to create an equally spaced vector given a begin and end point
real(dp),intent(in) :: xi,xf
integer, intent(in) :: length
real(dp),dimension(1:length) :: vec
integer ::i
real(dp) :: increment
increment = (xf-xi)/(real(length)-1)
vec(1) = xi
do i = 2,length
vec(i) = vec(i-1) + increment
end do
end function linspace
end module test
program paralleltest
use, intrinsic :: iso_fortran_env, only: dp => real64
use test
use :: omp_lib
implicit none
integer, parameter :: length = 1000
real(dp),dimension(length) :: x,y
real(dp) :: s
integer:: i,j
integer :: num_threads = 8
real(dp),dimension(length,length) :: SMatrix
x = linspace(length,.0d0,1.0d0)
y = linspace(length,2.0d0,3.0d0)
!$ call omp_set_num_threads(num_threads)
!$OMP PARALLEL DO
do i=1,size(x)
do j = 1,size(y)
call Addition(x(i),y(j),s)
SMatrix(i,j) = s
end do
end do
!$OMP END PARALLEL DO
open(unit=1,file ='Add6.dat')
do i= 1,size(x)
do j= 1,size(y)
write(1,*) x(i),";",y(j),";",SMatrix(i,j)
end do
end do
close(unit=1)
end program paralleltest
Я запускаю программу следующим образом gfortran-8 -fopenmp paralleltest.f03 -o pt.out -mcmodel=medium
, а затем export OMP_NUM_THREADS=8
Этот простой код ставит мне по крайней мере два больших вопроса о параллельной работе.Во-первых, если я запускаю с length = 1100
или выше, у меня появляется сообщение об ошибке Segmentation fault (core dump)
, но при меньших значениях оно запускается без проблем.Второе о времени, которое требуется.Когда я запускаю его с length = 1000
(запускаем с time ./pt.out
), это занимает 1,732s
, но если я запускаю его последовательно (без вызова библиотеки -fopenmp
и с taskset -c 4 time./pt.out
), это занимает 1,714s
.Я предполагаю, что разница между обоими способами возникает в более длинном и более сложном коде, где параллель более полезна.На самом деле, когда я попробовал это с более сложными вычислениями, работающими параллельно с восемью потоками, время было уменьшено вдвое, по сравнению с последовательным, а не восьмым, как я ожидал.В связи с этим мои вопросы: всегда ли доступна какая-либо оптимизация или она зависит от кода?и во-вторых, есть ли дружественный способ контролировать, какой поток выполняет итерацию?Это первый запуск первой итерации length/8
и т. Д., Аналогичный выполнению нескольких taskset
с различным кодом, где в каждой есть итерация, которую я хочу.