我是新来的优化,需要一些解释。。。
例如,我有下一个程序:
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测试中执行“高级热点分析”时。我在函数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%
据我所知,所有的指令都是配对的,这对push/pop指令的解码没有任何问题。。。
那么,为什么热点会出现,而且对于某些特定的前感受器(f.e.i7)可以去除它们呢?
谢谢你的帮助。
最佳答案
在这个级别上,热点分析可能不会指向导致给定基本块的大部分性能命中的确切指令。一条指令可能会因资源耗尽而暂停很长一段时间,这会导致许多指令被耗尽。例如,由于mov
s导致eax
和ebx
的重命名寄存器的旧副本比理想值挂起的时间更长,可能导致push
es和pop
s暂停,或者可能与前面jnz
的分支预测产生的管道气泡有关。
不过,这些都是猜测。选择暴露前端和后端暂停的VTune分析类型可能会有所帮助。不过,正如twalberg所说,这种分析和任何进一步的分析对于完成实际工作的代码都更有意义。
如果你的目标最终是提高总跑步时间,那么你可以运用很多其他的技巧。特别是,您在编译时知道循环要执行多少次,并且可以确定迭代之间没有依赖关系。在这些情况下展开和矢量化是微不足道的。将这里得到的输出与编译类似C代码时使用的指令进行比较,这些代码带有类似于“-O3-mtune=corei7”的标志。您可能根本看不到循环体,因为在最后一次迭代被抛出之前,所有循环体都会正常工作,但是如果您对循环体进行足够的调整,以诱使编译器认为每次都需要生成代码,那么您仍然可能看到使用了更有效的指令。
关于c - 针对特定处理器的优化,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22821432/