并行效率低,求解答
下面这段程序,通过改变nscanpts=1,10,40分别得到串行,并行1路,4路的时间,1路有10核。发现时间分别为 600s,5608s,15275s。不知道为什么并行效率这么低。用的是ivf编译器,且设置了并行计算的功能。program test1
implicit none
integer,parameter::nscanpts = 8
integer:: n=150000,m=1000000
integer i,j,k
real time1,time2,timescan(nscanpts),time3,time4
integer rel(nscanpts)
rel = 0
call cputime(time3)
!$OMP PARALLEL SHARED(n,rel,timescan,m), PRIVATE(i,time1,time2)
!$OMP DO
do i = 1, nscanpts
write(*,*) "iscan=",i
call cputime(time1)
do j = 1,n
do k = 1,m
rel(i) = rel(i) + k * j
end do
end do
call cputime(time2)
timescan(i) = time2-time1
end do
!$OMP END DO
!$OMP END PARALLEL
call writeTime(nscanpts,timescan)
call writeResult(nscanpts,rel)
call cputime(time4)
write(*,*) "Time=",time4-time3
end program
subroutine cputime(t)
implicit none
real, intent(out) :: t
integerdate_time(8)
character (len=10) big_ben(3)
call date_and_time(big_ben(1),big_ben(2),big_ben(3),date_time)
t = date_time(5)*3600 + date_time(6)*60 + date_time(7)+ &
date_time(8)*1.0d-3
return
end subroutine cputime
!****************************************************************
!
subroutine writeTime(n,time)
implicit none
integer, intent(in):: n
real, intent(in):: time(n)
integer:: fid=40, i
open (fid, file = 'timescan.dat', status = 'unknown')
write(fid,'(e16.8)') (time(i), i=1,n)
close(fid)
return
end subroutine writeTime
subroutine writeResult(n,r)
implicit none
integer, intent(in):: n
integer, intent(in):: r(n)
integer:: fid=41, i
open (fid, file = 'results.dat', status = 'unknown')
write(fid,'(i16)') (r(i), i=1,n)
close(fid)
return
end subroutine writeResult
大家好,后来经一位牛人指点,把并行设置改写为如下:(从原程序的第10行开始修改)发现并行1路,4路时间与串行相似。神啊,这是为什么?
!$OMP PARALLEL DO reduction(+:rel)
do i = 1, nscanpts
write(*,*) "iscan=",i
call cputime(time1)
do j = 1,n
do k = 1,m
rel(i) = rel(i) + k * j
end do
end do
call cputime(time2)
timescan(i) = time2-time1
end do
call writeTime(nscanpts,timescan)
call writeResult(nscanpts,rel)
call cputime(time4)
write(*,*) "Time=",time4-time3
end program
为什么修改了并行设置,并行计算效率提高那么多? OMP_NUM_THREADS 设置的多少? fcode 发表于 2014-9-4 22:28
OMP_NUM_THREADS 设置的多少?
没有设置。我试了下定义完初始变量后即第 7行后,添加下段程序: 结果发现,nscanpts=1,10,40时候,添加程序后时间会稍微长一点点。所以我觉得跟
OMP_NUM_THREADS 设置多少没有关系吧。
nThreads = nscanpts
Write(*,*) 'This Program will use',nThreads,' threads'
call omp_set_num_threads( nThreads )
This Program will use 1threads
iscan= 1
iscan= 2
iscan= 3
iscan= 4
iscan= 5
iscan= 6
iscan= 7
iscan= 8
Time= 24.85156
请按任意键继续. . .
This Program will use 4threads
iscan= 1
iscan= 5
iscan= 3
iscan= 7
iscan= 2
iscan= 8
iscan= 4
iscan= 6
Time= 13.57031
请按任意键继续. . .
在我这里,结果只与 OMP_NUM_THREADS 有关。
不管是用 !$OMP PARALLEL DO reduction(+:rel) 还是用顶楼的代码,都一样。
OMP_NUM_THREADS 越大,时间越少。
fcode 发表于 2014-9-9 09:15
在我这里,结果只与 OMP_NUM_THREADS 有关。
不管是用 !$OMP PARALLEL DO reduction(+:rel) 还是用顶楼的 ...
nscanpts恒定时,当然线程越多时间越少。我现在是希望并行计算时线程数等于nscanpts,即并行1路(10核),则打开线程数为10;并行4路(40核),打开线程数为40。这种情况下,发现第一种编程的单点串行,1路并行,4路并行时间分别为:697.371s,5707.329s,15275.02s.第二种的时间分别为:706.478s,704.85s,1130.24s.通过比较结果发现,如果rel属性定义为reduction,则并行效率明显提高。我不知道这是什么原因?
nscanpts 写法1 写法2
1 3.02 3.03
4 6.76 6.74
8 13.3 13.1
不同的 nscanpts 在我这里,两种写法也一样。(我没耐心等那么久,把 n 和 m 放小了)
fcode 发表于 2014-9-9 10:27
不同的 nscanpts 在我这里,两种写法也一样。(我没耐心等那么久,把 n 和 m 放小了)
...
谢谢你的回答。我找出问题所在了。原来是rel的结果超出整数范围了,所以算的结果都是错的,得出来的时间就没有参考价值了。谢谢
页:
[1]