代码对齐会显着影响性能
今天我发现示例代码在添加了一些不相关的代码后速度降低了 50%。调试后我发现问题出在循环对齐上。根据循环代码的放置,有不同的执行时间,例如:
| 地址 | 时间[我们] |
|---|---|
| 00007FF780A01270 | 980us |
| 00007FF7750B1280 | 1500us |
| 00007FF7750B1290 | 986us |
| 00007FF7750B12A0 | 1500us |
回答
在慢速情况下(即 00007FF7750B1280 和 00007FF7750B12A0),jne指令跨越 32 字节边界。“跳转条件代码”(JCC) 勘误表的缓解措施 ( https://www.intel.com/content/dam/support/us/en/documents/processors/mitigations-jump-conditional-code-erratum.pdf )防止此类指令缓存在 DSB 中。JCC 勘误表仅适用于基于 Skylake 的 CPU,这就是为什么 i5-3570k CPU 上不会出现此影响的原因。
正如 Peter Cordes 在评论中指出的那样,最近的编译器有一些选项可以尝试减轻这种影响。英特尔 JCC 勘误表 - 真的应该单独对待 JCC 吗?提到了 MSVC 的/QIntel-jcc-erratum选项;另一个相关问题是如何减轻英特尔 jcc 勘误对 gcc 的影响?
- IIRC, modern GCC/clang and/or possibly even `as` itself have options to try to mitigate this. But it's a recent effect so only the latest compiler versions know about it. Related: [Intel JCC Erratum - should JCC really be treated separately?](https://stackoverflow.com/q/62305998) mentions MSVC's `/QIntel-jcc-erratum` option. (And points out that even if the erratum only involved JCC, the mitigation definitely causes a problem for JMP/CALL/RET as well.)