Chinaunix首页 | 论坛 | 博客
  • 博客访问: 316607
  • 博文数量: 57
  • 博客积分: 146
  • 博客等级: 入伍新兵
  • 技术积分: 769
  • 用 户 组: 普通用户
  • 注册时间: 2012-05-29 14:57
文章分类
文章存档

2014年(39)

2013年(13)

2012年(5)

我的朋友

分类: C/C++

2014-05-06 16:29:20

环境:ubuntu gcc version 4.8.2

编译器就程序员写的代码变成CPU能理解机器代码。编译器的指令重排指开启编译器优化后,在不影响代码行为的前提下,代码的顺序会发生改变。

测试代码:

点击(此处)折叠或打开

  1. #include <stdio.h>

  2. int a , b;

  3. void main()
  4. {
  5.     a = b + 1;
  6.     b = 0x00;
  7.     return;
  8. }
首先,不开启编译器优化,执行指令:

点击(此处)折叠或打开

  1. gcc -S foo.c
生成汇编指令:

点击(此处)折叠或打开

  1. .file    "foo.c"
  2.     .comm    a,4,4
  3.     .comm    b,4,4
  4.     .text
  5.     .globl    main
  6.     .type    main, @function
  7. main:
  8. .LFB0:
  9.     .cfi_startproc
  10.     pushl    %ebp
  11.     .cfi_def_cfa_offset 8
  12.     .cfi_offset 5, -8
  13.     movl    %esp, %ebp
  14.     .cfi_def_cfa_register 5
  15.     movl    b, %eax
  16.     addl    $1, %eax
  17.     movl    %eax, a
  18.     movl    $0, b
  19.     nop
  20.     popl    %ebp
  21.     .cfi_restore 5
  22.     .cfi_def_cfa 4, 4
  23.     ret
  24.     .cfi_endproc
  25. .LFE0:
  26.     .size    main, .-main
  27.     .ident    "GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2"
  28.     .section    .note.GNU-stack,"",@progbits
代码中红色加粗的部分就是a=b+1,b=0的汇编指令。

然后,开启编译器优化,执行命令:

点击(此处)折叠或打开

  1. gcc -O2 -S foo.c
生成汇编代码:

点击(此处)折叠或打开

  1. .file    "foo.c"
  2.     .section    .text.startup,"ax",@progbits
  3.     .p2align 4,,15
  4.     .globl    main
  5.     .type    main, @function
  6. main:
  7. .LFB24:
  8.     .cfi_startproc
  9.     movl    b, %eax
  10.     movl    $0, b
  11.     addl    $1, %eax
  12.     movl    %eax, a
  13.     ret
  14.     .cfi_endproc
  15. .LFE24:
  16.     .size    main, .-main
  17.     .comm    b,4,4
  18.     .comm    a,4,4
  19.     .ident    "GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2"
  20.     .section    .note.GNU-stack,"",@progbits
代码中红色加粗的部分就是a=b+1,b=0的汇编指令。

未开优化的代码:

点击(此处)折叠或打开

  1.     movl    b, %eax
  2.     addl    $1, %eax
  3.     movl    %eax, a
  4.     movl    $0, b

开启优化的代码:

点击(此处)折叠或打开

  1.     movl    b, %eax
  2.     movl    $0, b
  3.     addl    $1, %eax
  4.     movl    %eax, a
对比后,发现为开启优化的代码执行顺序是a=b+1,b=0, 而开启优化后的代码执行顺序是b=0,a=b+1。

单核CPU系统中,可以通过compiler barriers来防止编译器优化导致的顺序重排。

点击(此处)折叠或打开

  1. #include <stdio.h>

  2. int a , b;

  3. void main()
  4. {
  5.     a = b + 1;
  6.     asm volatile("" ::: "memory");
  7.     b = 0x00;
  8.     return;
  9. }
开启优化后,不会打乱代码的执行顺寻。



阅读(1907) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~