随想录(代码优化中的两个问题)

来源:互联网 发布:js判断是否为整数数字 编辑:程序博客网 时间:2024/05/20 18:02


【 声明:版权所有,欢迎转载,请勿用于商业用途。  联系信箱:feixiaoxing @163.com】


    最近在代码优化的过程中,发现了两个问题。一个是全局变量的问题,一个是编译乱序的问题。因为一开始的时候没有注意到这些问题,所以现在才弄必然要付出更大的精力。为了说明这两个问题,我们可以写了例子说明一下。

// gcc -O2 -S test.c#include <stdio.h>int a;int b;void fun1(){a = 1;}void fun2(){while(!a);}void fun3(){b = a + 1;a = 0;}int main(int argc, char* argv[]) {return 1;}

    首先可以看fun2这里边的代码,这个全局变量在gcc -O2 -S test.c下情况如何呢?还有就是fun3中的两行代码会不会乱序呢?做到这些也不难,只要打开优化,看看对应的汇编文件就可以了。

.p2align 4,,15.globl fun2.typefun2, @functionfun2:movla, %eaxpushl%ebpmovl%esp, %ebptestl%eax, %eaxje.L7popl%ebpret.L7:jmp.L7.sizefun2, .-fun2.p2align 4,,15.globl fun3.typefun3, @functionfun3:movla, %eaxpushl%ebpmovl%esp, %ebpmovl$0, aaddl$1, %eaxmovl%eax, bpopl%ebpret.sizefun3, .-fun3.p2align 4,,15

    看看这段汇编代码,可以发现fun2中的循环其实就进行了一次,判断结束之后就死循环了。至于fun3呢,可以发现a=0其实提前执行了。一般来说,代码乱序没有问题,但是如果执行的是io地址,那就有问题了。唯一的方法就是添加一些变通的手段就可以了。至于效果嘛,大家看看反汇编的效果就可以了。

#include <stdio.h>volatile int a;int b;#define COMPILE_BARRIER() __asm__ __volatile__ ("":::"memory")void fun1(){a = 1;}void fun2(){while(!a);}void fun3(){b = a + 1;COMPILE_BARRIER();a = 0;}int main(int argc, char* argv[]) {return 1;}


1 0