C语言的volatile

volatile是通知编译器不要优化。这里有个例子volatile type qualifier - cppreference.com

#include <stdio.h>
#include <time.h>
 
int main(void)
{
    clock_t t = clock();
    double d = 0.0;
    for (int n = 0; n < 10000; ++n)
        for (int m = 0; m < 10000; ++m)
            d += d * n * m; // reads from and writes to a non-volatile 
    printf("Modified a non-volatile variable 100m times. "
           "Time used: %.2f seconds\n",
           (double)(clock() - t)/CLOCKS_PER_SEC);
 
    t = clock();
    volatile double vd = 0.0;
    //double vd = 0.0;
    double prod;
    for (int n = 0; n < 10000; ++n)
        for (int m = 0; m < 10000; ++m) {
            prod = vd * n * m; // reads from a volatile
            vd += prod; // reads from and writes to a volatile
        } 
    printf("Modified a volatile variable 100m times. "
           "Time used: %.2f seconds\n",
           (double)(clock() - t)/CLOCKS_PER_SEC);
}

在release模式下运行结果是:

Modified a non-volatile variable 100m times. Time used: 0.00 seconds
Modified a volatile variable 100m times. Time used: 0.40 seconds

反汇编后发现,第一个计算部分,直接被优化掉了。从5b9到5d7之间,没有乘加的运算。所以运行时间是零。改变循环次数,更能反应出优化的效果。

00000000000005a0 <main>:
 5a0:   53                      push   %rbx
 5a1:   48 83 ec 10             sub    $0x10,%rsp
 5a5:   e8 c6 ff ff ff          callq  570 <clock@plt>
 5aa:   48 89 c3                mov    %rax,%rbx
 5ad:   e8 be ff ff ff          callq  570 <clock@plt>
 5b2:   66 0f ef c0             pxor   %xmm0,%xmm0
 5b6:   48 29 d8                sub    %rbx,%rax
 5b9:   48 8d 35 58 02 00 00    lea    0x258(%rip),%rsi        # 818 <_IO_stdin_used+0x8>
 5c0:   bf 01 00 00 00          mov    $0x1,%edi
 5c5:   f2 48 0f 2a c0          cvtsi2sd %rax,%xmm0
 5ca:   b8 01 00 00 00          mov    $0x1,%eax
 5cf:   f2 0f 5e 05 d1 02 00    divsd  0x2d1(%rip),%xmm0        # 8a8 <_IO_stdin_used+0x98>
 5d6:   00
 5d7:   e8 a4 ff ff ff          callq  580 <__printf_chk@plt>
 5dc:   e8 8f ff ff ff          callq  570 <clock@plt>
 5e1:   48 c7 44 24 08 00 00    movq   $0x0,0x8(%rsp)
 5e8:   00 00
 5ea:   48 89 c3                mov    %rax,%rbx
 5ed:   31 d2                   xor    %edx,%edx
 5ef:   90                      nop
 5f0:   66 0f ef db             pxor   %xmm3,%xmm3
 5f4:   31 c0                   xor    %eax,%eax
 5f6:   f2 0f 2a da             cvtsi2sd %edx,%xmm3
 5fa:   66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)
 600:   66 0f ef d2             pxor   %xmm2,%xmm2
 604:   f2 0f 10 44 24 08       movsd  0x8(%rsp),%xmm0
 60a:   f2 0f 10 4c 24 08       movsd  0x8(%rsp),%xmm1
 610:   f2 0f 2a d0             cvtsi2sd %eax,%xmm2
 614:   f2 0f 59 c3             mulsd  %xmm3,%xmm0
 618:   83 c0 01                add    $0x1,%eax
 61b:   3d 10 27 00 00          cmp    $0x2710,%eax
 620:   f2 0f 59 c2             mulsd  %xmm2,%xmm0
 624:   f2 0f 58 c1             addsd  %xmm1,%xmm0
 628:   f2 0f 11 44 24 08       movsd  %xmm0,0x8(%rsp)
 62e:   75 d0                   jne    600 <main+0x60>
 630:   83 c2 01                add    $0x1,%edx
 633:   81 fa 10 27 00 00       cmp    $0x2710,%edx
 639:   75 b5                   jne    5f0 <main+0x50>
 63b:   e8 30 ff ff ff          callq  570 <clock@plt>
 640:   66 0f ef c0             pxor   %xmm0,%xmm0
 644:   48 29 d8                sub    %rbx,%rax
 647:   48 8d 35 12 02 00 00    lea    0x212(%rip),%rsi        # 860 <_IO_stdin_used+0x50>
 64e:   bf 01 00 00 00          mov    $0x1,%edi
 653:   f2 48 0f 2a c0          cvtsi2sd %rax,%xmm0
 658:   b8 01 00 00 00          mov    $0x1,%eax
 65d:   f2 0f 5e 05 43 02 00    divsd  0x243(%rip),%xmm0        # 8a8 <_IO_stdin_used+0x98>
 664:   00
 665:   e8 16 ff ff ff          callq  580 <__printf_chk@plt>
 66a:   48 83 c4 10             add    $0x10,%rsp
 66e:   31 c0                   xor    %eax,%eax
 670:   5b                      pop    %rbx
 671:   c3                      retq
 672:   66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
 679:   00 00 00
 67c:   0f 1f 40 00             nopl   0x0(%rax)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值