环境:ubuntu gcc version 4.8.2
编译器就程序员写的代码变成CPU能理解机器代码。编译器的指令重排指开启编译器优化后,在不影响代码行为的前提下,代码的顺序会发生改变。
测试代码:
-
#include <stdio.h>
-
-
int a , b;
-
-
void main()
-
{
-
a = b + 1;
-
b = 0x00;
-
return;
-
}
首先,不开启编译器优化,执行指令:
生成汇编指令:
-
.file "foo.c"
-
.comm a,4,4
-
.comm b,4,4
-
.text
-
.globl main
-
.type main, @function
-
main:
-
.LFB0:
-
.cfi_startproc
-
pushl %ebp
-
.cfi_def_cfa_offset 8
-
.cfi_offset 5, -8
-
movl %esp, %ebp
-
.cfi_def_cfa_register 5
-
movl b, %eax
-
addl $1, %eax
-
movl %eax, a
-
movl $0, b
-
nop
-
popl %ebp
-
.cfi_restore 5
-
.cfi_def_cfa 4, 4
-
ret
-
.cfi_endproc
-
.LFE0:
-
.size main, .-main
-
.ident "GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2"
-
.section .note.GNU-stack,"",@progbits
代码中红色加粗的部分就是a=b+1,b=0的汇编指令。
然后,开启编译器优化,执行命令:
生成汇编代码:
-
.file "foo.c"
-
.section .text.startup,"ax",@progbits
-
.p2align 4,,15
-
.globl main
-
.type main, @function
-
main:
-
.LFB24:
-
.cfi_startproc
-
movl b, %eax
-
movl $0, b
-
addl $1, %eax
-
movl %eax, a
-
ret
-
.cfi_endproc
-
.LFE24:
-
.size main, .-main
-
.comm b,4,4
-
.comm a,4,4
-
.ident "GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2"
-
.section .note.GNU-stack,"",@progbits
代码中红色加粗的部分就是a=b+1,b=0的汇编指令。
未开优化的代码:
-
movl b, %eax
-
addl $1, %eax
-
movl %eax, a
-
movl $0, b
开启优化的代码:
-
movl b, %eax
-
movl $0, b
-
addl $1, %eax
-
movl %eax, a
对比后,发现为开启优化的代码执行顺序是a=b+1,b=0, 而开启优化后的代码执行顺序是b=0,a=b+1。
单核CPU系统中,可以通过compiler barriers来防止编译器优化导致的顺序重排。
-
#include <stdio.h>
-
-
int a , b;
-
-
void main()
-
{
-
a = b + 1;
-
asm volatile("" ::: "memory");
-
b = 0x00;
-
return;
-
}
开启优化后,不会打乱代码的执行顺寻。
阅读(1963) | 评论(0) | 转发(0) |