特定处理器的优化

时间:2014-04-02 19:43:35

标签: c optimization assembly

我是优化新手,需要一些解释......

例如,我有下一个程序:

int main() {
    for (int i = 0; i < 2000000; i++) {
        __asm {
                push esi
                push edi

                inc ebx
                inc eax
                mov ebx, 0xffffffff
                mov eax, 0xaaaaaaaa

                pop edi
                pop esi
        }
    }

    return 0;
}

所以当我在vtune测试中做 - &#34;高级热点分析&#34;。我在函数main中得到了它,这是一些热点:

Address Source Line Assembly    CPU Time: Total by Utilization  CPU Time: Self by Utilization   Instructions Retired: Total Instructions Retired: Self  Overhead and Spin Time: Total   Overhead and Spin Time: Self    Wait Time: Total    Wait Time: Self Inactive Time: Total    Inactive Time: Self
0x401000        Block 1:            0.0%        0.0%        0.0%        0.0%    
0x401000    1   push ebx            0.0%        0.0%        0.0%        0.0%    
0x401001    1   push esi            0.0%        0.0%        0.0%        0.0%    
0x401002    1   push edi            0.0%        0.0%        0.0%        0.0%    
0x401003    3   mov ecx, 0x1e8480           0.0%        0.0%        0.0%        0.0%    
0x401008        Block 2:            0.0%        0.0%        0.0%        0.0%    
0x401008    5   push esi    0ms 0ms 62.3%   14,956,555  0.0%    0ms 0.0%    0ms 0.0%    0ms
0x401009    6   push edi    0.872ms 0.872ms 0.5%    116,752 0.0%    0ms 0.0%    0ms 0.0%    0ms
0x40100a    8   inc ebx         0.0%        0.0%        0.0%        0.0%    
0x40100b    9   inc eax         0.0%        0.0%        0.0%        0.0%    
0x40100c    10  mov ebx, 0xffffffff         0.0%        0.0%        0.0%        0.0%    
0x401011    11  mov eax, 0xaaaaaaaa         0.0%        0.0%        0.0%        0.0%    
0x401016    13  pop edi         0.0%        0.0%        0.0%        0.0%    
0x401017    14  pop esi 2.923ms 2.923ms 20.6%   4,950,489   0.0%    0ms 8.5%    0.007ms 0.0%    0ms
0x401018    4   dec ecx 0.872ms 0.872ms 6.7%    1,613,429   0.0%    0ms 0.0%    0ms 0.0%    0ms
0x401019    4   jnz 0x401008 <Block 2>          0.0%        0.0%        0.0%        0.0%    
0x40101b        Block 3:            0.0%        0.0%        0.0%        0.0%    
0x40101b    19  pop edi         0.0%        0.0%        0.0%        0.0%    
0x40101c    19  pop esi         0.0%        0.0%        0.0%        0.0%    
0x40101d    19  xor eax, eax            0.0%        0.0%        0.0%        0.0%    
0x40101f    19  pop ebx         0.0%        0.0%        0.0%        0.0%    
0x401020    19  ret             0.0%        0.0%        0.0%        0.0%    

据我所知,所有指令都是配对,这对推/弹指令的解码没有任何问题... 那么为什么热点出现并且可以为某些特定的程序删除它们(f.e. i7)?

感谢您的帮助。

2 个答案:

答案 0 :(得分:0)

这闻起来很像过早优化。实际情况是,优化并不是要完全消除热点,而是更多地关注减少某些关键代码路径热点的影响。在这个特定的例子中,没有办法避免每个asm指令将被执行一定次数的事实,而现实是一些指令,就其本质而言,执行时自然需要更长的时间。某些平台。 PUSH / POP指令写入和读取存储器并更新寄存器,以及某些边界检查等.INC和MOV指令只是更新寄存器(一旦经过一次循环,MOV指令的立即操作数)在指令高速缓存中,并且循环足够小,它们不会被驱逐,因此所有指令上的指令获取/解码开销不是主要因素)。 PUSH / POP操作的缓存和内存周期意味着它们执行INC / MOV操作的时间要长得多,因此看起来占用了大部分执行时间。

如果你想避免PUSH / POP指令的执行时间,你可以1)消除PUSH / POP指令,因为它们无论如何都没有完成任何事情,但是其他指令似乎会占用大量的执行时间,或2)引入“扩散负载”的其他指令,或3)尝试优化真实的东西,而不是真正无效的小例子。

答案 1 :(得分:0)

在此级别,热点分析可能不会指向负责给定基本块的大部分性能命中的确切指令。由于资源耗尽而导致许多指令耗尽,因此一条指令可能会停滞很长时间。例如,由于mov导致eaxebx的重命名寄存器的旧副本挂起的时间超过理想值,因此您可能正在用完加载缓冲区,这反过来导致停滞在pushpop上。或者它可能与前面jnz的分支预测中的管道气泡有关。

但这些都是猜测。选择暴露前端和后端停顿的VTune分析类型可能会有所帮助。就像twalberg所说的那样,这种分析以及任何进一步对于完成实际工作的代码更有意义。

如果您的目标最终是改善总运行时间,那么您可以应用许多其他技术。特别是,您在编译时知道循环执行的次数,并且可以确定迭代之间没有依赖关系。在这些情况下,展开和矢量化是微不足道的。将您在此处获得的输出与编译类似C代码时使用的指令进行比较,其中包含类似“-O3 -mtune = corei7”的标志。您可能根本看不到任何循环体,因为所有工作都会进行,直到最后一次迭代被抛出,但如果您调整它足以欺骗编译器认为它需要每次生成代码,您仍然可能会看到更有效的指令被使用。