Villain 发表于 2014-12-16 08:58:49

小白求指点,如何使用OpenMP

今天下了一个OpenMP的PDF并试验了一下,发现运算时间根本没有减少
以下是代码:
integer::I
integer,dimension(100000)::a
real::stime,etime
!!$OMP PARALLEL
!Print*,"ok"
!!$OMP END PARALLEL

call cpu_time(stime)

!$OMP DO
do i=1,100000
do j=1,100000
    k=J
enddo
a(i)=i**2+1
end do
!$OMP END DO
call cpu_time(etime)
write(*,*)stime,etime,etime-stime

pause
end


这个的运行时间是18.46812

而 把omp的语句删除之后运行时间是18.37692

是我打开方式有问题吗?

!$OMP PARALLEL
Print*,"ok"
!$OMP END PARALLEL
这段代码检查了一下,系统是8核的,也确实出现了八个OK,说明设置没有错误。

li913 发表于 2014-12-16 10:25:29

两个问题:
1、OMP并行,检测耗时不用 CPU_time,用 OMP_get_wtime

li913 发表于 2014-12-16 10:29:20

2、所有并行语句都必须包含在并行域中,否则视为串行。
!$OMP PARALLEL DO clause1 clause2 ...
...
!$OMP END PARALLEL DO

这里有中文资料
http://fcode.cn/resource_ebook-24-1.html

Villain 发表于 2014-12-17 08:54:13

li913 发表于 2014-12-16 10:29
2、所有并行语句都必须包含在并行域中,否则视为串行。
!$OMP PARALLEL DO clause1 clause2 ...
...


谢谢指点。
也就是说在用OMP的时候,必须要人为的划分一片并行域并在这块域中执行并行代码,而不是说让计算机自己判断。
但是我用
!$OMP PARALLEL DO clause1 clause2 ...
...
!$OMP END PARALLEL DO
这个的时候老是报错,最后就是
!$OMP PARALLEL
...
!$OMP END PARALLEL
来划分并行域。
并且执行时间是23秒左右,反而比单线程的18秒还要慢:-L:-L:-L
这就是传说中的不做死就不会死?

还有cpu_time 跟OMP_get_wtime()的区别是什么?是不是cpu_time只是返回当前运行cpu_time函数的线程的时间而非每一个线程执行完后的时间?

谢谢~~~~

li913 发表于 2014-12-17 11:26:46

1、并行循环有两种表示,一是将并行和循环分开,二是联合表示;
!$OMP PARALLEL
!$OMP PARALLEL DO
...第1种
!$OMP ENDDO
!$OMP END PARALLEL

!$OMP PARALLEL DO
...第二种
!$OMP END PARALLEL DO

2、并行处理不好可能比串行更耗时;
3、简单理解,cpu_time是所有核心耗时的总和,而OMP_get_wtime是程序运行的真实时间。n个核并行时,前者大致是后者的n倍。

li913 发表于 2014-12-17 11:29:27

4、对比效率时,需在release模式下,并关闭优化。

Villain 发表于 2014-12-18 09:19:14

li913 发表于 2014-12-17 11:29
4、对比效率时,需在release模式下,并关闭优化。

太感谢了,谢谢指点!!

andy8496 发表于 2014-12-18 16:13:50

li913 发表于 2014-12-17 11:29
4、对比效率时,需在release模式下,并关闭优化。

这个原因何在?

li913 发表于 2014-12-18 17:54:41

1、debug模式下,会执行许多额外的调试代码,这些代码与程序任务本身无关;
2、编译器优化是非线性的(也可理解为不确定, 例如循环400次和200次的时间之比不一定是2倍),同样难以反映加速比(串行运行时间/并行运行时间)。
因此对比需在release模式下,并关闭优化。

百事可乐 发表于 2014-12-21 12:05:06

现在编译器有自动矢量化 , 多核 CPU 自动调度等.

所以简单的代码用 OpenMP 不一定就能快多少
页: [1]
查看完整版本: 小白求指点,如何使用OpenMP