计算linux下的循环次数

时间:2012-03-19 19:24:30

标签: c++ c linux assembly

我的汇编代码是这两条指令的100倍:

    movl    %eax, -16(%rbp)
    movl    -12(%rbp), %eax

这对应于这个c代码循环:

 int i;
    int a=5, b;
    for (i=0 ; i < sptr->numberOfIterations ; i += 100){
        b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;
        b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;
        b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;
        b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;
        b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;
        b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;
        b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;
        b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;
        b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;
        b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a; // 100 assignments 
    }

为什么b = a的操作;去两个指示?我怎么计算它所需的周期数(每个b=a;)是一个周期?

我用g++

编译了它

3 个答案:

答案 0 :(得分:3)

b = a 确实接受两条指令:首先将a的值移入寄存器,然后将该寄存器的值移入b的内存中地址:

movl    %eax, -16(%rbp) // move a's value to eax
movl    -12(%rbp), %eax // move eax's value into b's address.

由于您反复重复此指令,编译器会意识到一个b=a将与100相同。因此,它只是将for循环缩减为单个b=a指令。< / p>

编辑:由于您说这些行出现了100次,因此编译器会对您的代码执行 no optmimizations 。您的代码的ASM结果正是您所写的,是b=a的100倍。

答案 1 :(得分:3)

您应该让编译器有机会优化代码。使用正确的优化标志-O3 -march=native,我的编译器(gcc)能够将所有这些减少到以下行:

movl    $5, %eax

没有循环,重复代码,没有。

因此,您的编译器可能会也可能不会进行优化以及许多您看不到的内容。和处理器不同。我这里能够将常数5放入立即数,并且根本不创建变量a

答案 2 :(得分:1)

在具有任何合理优化设置的任何合理编译器下,此代码:

int i;
int a=5, b;
for (i=0 ; i < sptr->numberOfIterations ; i += 100){
    b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;
    b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;
    b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;
    b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;
    b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;
    b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;
    b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;
    b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;
    b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;
    b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a;b=a; // 100 assignments 
}

将优化为:

int i;
for (i=0; i < sptr->numberOfIterations; i += 100); // Possibly further reduced from O(n) into O(1).
int a = 5;
int b = 5;

或者,如果从未使用iab,则编译器可以将其优化为:

;