回 帖 发 新 帖 刷新版面

主题:[讨论]同样的程序用Intel Visual Fortran反而比CVF慢一倍多

不是都说Intel Visual Fortran要快吗?
我的是XP系统,
CPU参数如下:
Intel 酷睿2双核 T8300(Intel 酷睿2双核 T8300)
类别:CPU     品牌:Intel 参考价格: 插槽类型:BGA479,PGA478 CPU主频:2400MHz 制作工艺:45 纳米 二级缓存:3MB 核心数量:双核心 双线程热设计功:35W 总线类型:FSB总线 800MHz适用类型:笔记本 倍频:12倍 外频:200MHz 内核电压:1-1.250V 超线程技:不支持 晶体管数:410百万 生产厂商:Intel CPU系列:酷睿2双核 总线频率:800MHz 线程数:双线程 

请高人指教

回复列表 (共12个回复)

沙发

给出编译开关? 否则无法比较

板凳

如果你的程序里有很多MatMul那就正常了IVF在这方面确实还不如当年的CVF。

3 楼

[quote]如果你的程序里有很多MatMul那就正常了IVF在这方面确实还不如当年的CVF。[/quote]
是么,不好评判吧。我确信ivf的matmul在开高级优化时使用了mkl的优化库gemm。

4 楼

[quote][quote]如果你的程序里有很多MatMul那就正常了IVF在这方面确实还不如当年的CVF。[/quote]
是么,不好评判吧。我确信ivf的matmul在开高级优化时使用了mkl的优化库gemm。[/quote]
我不知道用什么樣的開關才能用MKL里的東東,但我很確定我的程序之前用的Transpose+MatMul,在IVF編譯(選項與CVF相同)結果與CVF相比時確實讓我大跌眼鏡~~~
不過需要說明的是,我的矩陣操作全都是小矩陣。

記得以前看過CVF的Release代碼,好像沒有函數調用,直接展開的。
而如果IVF真是用的MKL里的GEMM,那就沒辦法了,函數調用的開銷只能讓這些小矩陣操作得不償失:)

5 楼

[quote][quote][quote]如果你的程序里有很多MatMul那就正常了IVF在这方面确实还不如当年的CVF。[/quote]
是么,不好评判吧。我确信ivf的matmul在开高级优化时使用了mkl的优化库gemm。[/quote]
我不知道用什么樣的開關才能用MKL里的東東,但我很確定我的程序之前用的Transpose+MatMul,在IVF編譯(選項與CVF相同)結果與CVF相比時確實讓我大跌眼鏡~~~
不過需要說明的是,我的矩陣操作全都是小矩陣。

記得以前看過CVF的Release代碼,好像沒有函數調用,直接展開的。
而如果IVF真是用的MKL里的GEMM,那就沒辦法了,函數調用的開銷只能讓這些小矩陣操作得不償失:)[/quote]
ipo优化没起作用么?ivf的ipo可以和lib一起用的,不像gcc,使用lib的lto必须使用lto插件,而这个插件移植到windows下工作还不是很正常

6 楼

[quote]给出编译开关? 否则无法比较[/quote]

什么是编译开关?请指教
以及如何操作?谢谢!

我又用如下小程序测试,Intel VF用了59秒多,而CVF是23秒多
    CALL CPU_TIME(time_begin)
    
    do 5 i=1,1000000000
    CALL RANDOM_NUMBER (x)
    if (x.lt.0.00000001) then
    print *,x
    end if
5    continue

    CALL CPU_TIME(time_end)
    WRITE(*,*)"consumed CPU_time(s):", time_end - time_begin

    end

但奇怪的是我原来测试的程序现在用两个编译器计算的速度基本差不多了

7 楼

6l的程序很无趣,这个不是比较的两个编译器的性能,而是比较的两个编译器的产生随机数的耗时+IO速度+随机的人品。
print输出语句也是占用时间的,而输出算IO慢速设备,怎么着也比内存慢,设想cvf运气很好,if语句一句都没执行,那么他就缺少了IO的耗时,ivf如果运气极差,if执行了1000000000次,那就占用了最长的IO时间,这就是随机的人品问题。
IO速度和底层api、硬件有关,这个一般相差不大,除非是封装移植。产生随机数的函数就难说了,也可能cvf要快,也可能ivf要快,毕竟他俩不开源,都不知道是什么算法。
但是三者相加,无疑随机人品很重要,不小心可能就N倍的时间了。

8 楼

lz可以测试这个程序

program int_sin
implicit none

integer, parameter :: DP = kind(0.0D0)

real(DP), parameter :: pi = 3.141592653589793238_DP 

real(DP), parameter :: interval_begin = 0.0_DP
real(DP), parameter :: interval_end   = 2.0_DP * pi

real(DP) :: step, sum, x_i
integer :: N, i, j
real clock_start, clock_finish

write (*,'(A)') "  "
write (*,'(A)') "    Number of    | Computed Integral |"
write (*,'(A)') " Interior Points |                   |"
call cpu_time (clock_start)

do j=2,26
  write (*,'(A)') "--------------------------------------"
  N = 2**j
  step = (interval_end - interval_begin) / real(N,DP);
  
  sum = INTEG_FUNC(interval_begin) * (step / 2.0_DP)
  
  do i=1,N-1
    x_i = real(i,DP) * step
    sum = sum + (INTEG_FUNC(x_i) * step)
    end do
    
  ! Add approximate area in last rectangle for f(xN) * (step/2) 
  sum = sum + (INTEG_FUNC(interval_end) * (step / 2.0_DP))
  
  write (*,'(T5,I10,T18,"|",2X,1P,E14.7,T38,"|")') N, sum
  end do

call cpu_time(clock_finish)
write (*,'(A)') "--------------------------------------"
write (*,'(A)') "  "
write (*,*) "CPU Time = ",(clock_finish - clock_start), " seconds"

contains

real(DP) function INTEG_FUNC (x)
real(DP), intent(IN) :: x

INTEG_FUNC = abs(sin(x))
return
end function INTEG_FUNC

end program int_sin

这个程序在我电脑上(Lenovo Y450 core2 T6600)

ivf的编译开关为/fast /O3 /Qipo /QxHost /arch:SSE3 /Qparallel
耗时为 1.797s

gfortran编译开关为-O3 -fivopts -ftree-loop-linear -ftree-vectorize -fforce-addr -fomit-frame-pointer -fno-bounds-check -funroll-loops -march=native -mfpmath=sse -mmmx -msse -msse2 -msse3 -ftree-parallelize-loops=2
耗时为 8.242s

ps:这个例子(无依赖循环)也说明,intel和gcc的编译器的自动并行化对fortran影响甚微(CPU 50%)。如果相同算法转换成C代码的话,intel耗时几乎不变(CPU 50%),gcc耗时减少一半(4s左右 CPU 100%)。intel的自动并行化很不靠谱,gcc的自动并行对C的效果还是不错的。

9 楼

谢谢楼上兄弟

10 楼

[quote]6l的程序很无趣,这个不是比较的两个编译器的性能,而是比较的两个编译器的产生随机数的耗时+IO速度+随机的人品。
print输出语句也是占用时间的,而输出算IO慢速设备,怎么着也比内存慢,设想cvf运气很好,if语句一句都没执行,那么他就缺少了IO的耗时,ivf如果运气极差,if执行了1000000000次,那就占用了最长的IO时间,这就是随机的人品问题。
IO速度和底层api、硬件有关,这个一般相差不大,除非是封装移植。产生随机数的函数就难说了,也可能cvf要快,也可能ivf要快,毕竟他俩不开源,都不知道是什么算法。
但是三者相加,无疑随机人品很重要,不小心可能就N倍的时间了。[/quote]


谢谢啊
说明一下,两个编译器产生的结果是一样的,即print输出同样数目的小随机数,而且其数值一样,由此可以推断两个编译器产生随机数函数可能是一样的。在这之前我也试过用两个编译器分别产生一些随机数列,通过比较是一样的。
不然我也不会这样比较   PS:我的程序随机数也用得多

刚才比较了计算三角函数IVF很占优势

我来回复

您尚未登录,请登录后再回复。点此登录或注册