24小时热门版块排行榜    

CyRhmU.jpeg
查看: 2520  |  回复: 9
本帖产生 1 个 程序强帖 ,点击这里进行查看

coolrainbow

木虫 (著名写手)

未来国家冻凉

[交流] 【转帖】intel Fortran编译器的一个“危险”优化已有9人参与

源地址:http://hi.baidu.com/coolrainbow/ ... d6c40c5aaf535e.html

今天无意中发现了intel编译器优化的一个问题。我有一个程序,大致是这样

program main
    integer, parameter :: n = 1000
    real(kind = 8) value(n)
    integer i
   
    call computation(value)

    do i = 1, n
         write (*,*) value(n)
    enddo
end

其中computation是一个计算量极大的subroutine。利用intel编译编译,分别令n = 1000和n = 5000,不优化和优化执行的时间

n           1000              5000
O0        12min             60min
O2          7min             36min

后来,我无意中将输出函数的代码取消了,也即:

program main
    integer, parameter :: n = 1000
    real(kind = 8) value(n)
    integer i
   
    call computation(value)
end

再次运行,惊现!

n           1000              5000
O0        11min30s          59min
O2         0.003s            0.003s

看到这种结果,我目瞪口呆,可是当我发现n=1000和5000是执行时间相同,我就猜测computation这个子过程根本就没有执行。那么为什么没执行呢?我猜测:intel编译器在O2过程中,发现后续代码没有用到value这个数组,也没有牵扯到computation函数内部的任何内容,因此干脆将其优化掉了

这个猜测对吗?决定看一下。在n=1000时候,我将两段代码编译成汇编语言:
ifort -O0 -o pO0.s -S   foo.f90
ifort -O2 -o pO2.s -S   foo.f90

首先观察pO0.s,发现:

# -- Begin MAIN__
.........
   call      foo_mp_computation_                #369.10
........
# -- End MAIN__

果然,main中调用了computation函数。再看pO2.s,我们发现:

# -- Begin MAIN__
........
# -- End MAIN__

确确实实没有发现computation函数调用的汇编代码,哈哈,看来我的推测是对的。

下面这段比较小的代码,大家可以自己用编译器编译一下,我用ifort编译了一下,和上面是一样的,通过汇编语言可以发现,开启O2时,汇编代码的MAIN中没有出现调用perform函数的内容。当然,如果我说的不对,希望大家指教,呵呵。

subroutine perform(value, n)
   integer n
   real(kind = 8) value(n)

   integer i

   do i = 1, n
       value(i) = 2.0*i
   enddo
return
end subroutine


program main

   integer, parameter :: n = 10
   real(kind = 8) value(n)

   call perform(value,n)

end

事实上,这个例子表明,编译器的优化选项确实有一定的危险性,尽管在这个例子中,并没有什么问题,但是在投产级别的软件中启动优化选项时的确要慎重,一般不要启用O3这种激进的优化,即使启用也一定要试验确定代码无误后才行
回复此楼

» 猜你喜欢

» 本主题相关价值贴推荐,对您同样有帮助:

技术博客:http://hi.baidu.com/coolrainbow/blog
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

hakekill

木虫 (小有名气)


小木虫(金币+0.5):给个红包,谢谢回帖交流
这个确实是第一次听说,不知道gfortran是不是这样
2楼2010-09-12 19:06:22
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

ifmc1234

木虫 (著名写手)


小木虫(金币+0.5):给个红包,谢谢回帖交流
引用回帖:
Originally posted by coolrainbow at 2010-09-12 18:21:45:
源地址:http://hi.baidu.com/coolrainbow/ ... d6c40c5aaf535e.html

今天无意中发现了intel编译器优化的一个问题。我有一个程序,大致是这样

program main
    integer, param ...

楼主正解。很多软件都说了这个问题。
所以有些软件(需要自己编译的)告诉使用者要把编译结果和他们给的例子进行比较。
3楼2010-09-12 19:21:14
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

coolrainbow

木虫 (著名写手)

未来国家冻凉

引用回帖:
Originally posted by hakekill at 2010-09-12 19:06:22:
这个确实是第一次听说,不知道gfortran是不是这样

gfortran似乎没有这样,比如刚才那段代码

f95 -O0
CODE:
.LCFI4:
         movl    $options.5.935, %esi
         movl    $7, %edi
         call    _gfortran_set_options
         leaq    -80(%rbp), %rdi
         movl    $.LC0, %esi
         movl    $0, %eax
         call    perform_
         leave
         ret
.LFE3:

f95 -O2
CODE:
.LCFI0:
        movl    $options.5.929, %esi
        movl    $7, %edi
        call    _gfortran_set_options
        movq    %rsp, %rdi
        movl    $.LC0, %esi
        xorl    %eax, %eax
        call    perform_
        addq    $88, %rsp
        ret
.LFE3:

技术博客:http://hi.baidu.com/coolrainbow/blog
4楼2010-09-12 21:00:35
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

maomao1210

金虫 (正式写手)


小木虫(金币+0.5):给个红包,谢谢回帖交流
引用回帖:
Originally posted by coolrainbow at 2010-09-12 18:21:45:
源地址:http://hi.baidu.com/coolrainbow/ ... d6c40c5aaf535e.html

今天无意中发现了intel编译器优化的一个问题。我有一个程序,大致是这样

program main
    integer, param ...

学习了
5楼2010-09-13 09:08:38
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

tjyl

金虫 (正式写手)

★ ★ ★
小木虫(金币+0.5):给个红包,谢谢回帖交流
nono2009(金币+2):鼓励交流 2010-09-13 15:12:35
只能说有些人现在还用循环固定次数来延时不起作用了
gcc也会做这样的优化的,不是什么奇怪的。
6楼2010-09-13 13:06:09
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

weiwei43

至尊木虫 (正式写手)


小木虫(金币+0.5):给个红包,谢谢回帖交流
原来发现编译时debug和release结果不一样,是不是也是优化的结果不同?
7楼2010-09-26 19:05:38
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

bulrush2008

木虫 (初入文坛)


小木虫: 金币+0.5, 给个红包,谢谢回帖
前不久我也发现了类似的问题:用ifort -Ox (x=1,2,3)优化编译,程序都会莫名其妙的爆掉,而且输出对测试“探针”敏感。后来才发现用ifort -O0编译,问题就没了。危险啊。
行有不惬于心则馁已。
8楼2016-01-21 22:22:59
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

virtualzx

木虫 (著名写手)


小木虫: 金币+0.5, 给个红包,谢谢回帖
这不是编译器的问题,是你程序本身有bug,而优化引爆了bug。你的问题很可能是变量没初始化,下标越界等。

如果你调用了一个很复杂的函数,但是完全没用到它的输出,也没有改变任何函数外的变量,那说明这个函数本身就是一段垃圾代码,优化就是应该把它拿掉的。这不能叫危险,反倒说明它派上用场了

发自小木虫IOS客户端
9楼2016-01-22 04:17:29
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

hwliu11

新虫 (初入文坛)


小木虫: 金币+0.5, 给个红包,谢谢回帖
开启优化代码出问题,代码多少都是有问题的
10楼2016-01-22 14:15:23
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖
相关版块跳转 我要订阅楼主 coolrainbow 的主题更新
普通表情 高级回复(可上传附件)
信息提示
请填处理意见