gcc - movsbl near ret 对性能有好处吗?
问题描述
char c;
int f()
{
return c ^ 1;
}
gcc 把它编译成类似的东西
movzbl c(%rip), %eax
xorl $1, %eax
movsbl %al, %eax
ret
由于一些乱序或超标量特性,它有用吗?
解决方案
不,这是 GCC 错过的优化;C 首先可以合法地进行符号扩展负载。您应该使用关键字“missed-optimization”在 GCC bugzilla 上报告它。
clang、ICC 和 MSVC(在 Godbolt 上)将其编译为预期的
f:
movsbl c(%rip), %eax # sign extend first
xorl $1, %eax
retq
即使试图用这个 C 将 GCC 手持到那个代码生成中,也无法让 GCC 做到这一点:
int f() {
int tmp = c;
tmp ^= 1;
return tmp;
}
我猜也许 GCC 决定只加载 1 个字节并在之后而不是之前进行符号扩展。IDK 为什么它认为这是一个好主意。但无论如何,为了避免对 RAX 旧值的错误依赖,需要对 32 位进行某种扩展。
以这种方式编写 C 会使 ICC 陷入这种错过的优化,而不是 MSVC 或 clang。他们仍然首先将其优化为符号扩展,因为他们知道 XOR 不能更改任何高位。
int extend_after() {
char tmp = c^1;
return tmp;
}
现在 ICC 就像 GCC,但由于某种原因符号一直扩展到 64 位:
extend_after:
movzbl c(%rip), %eax #10.16
xorl $1, %eax #10.18
movsbq %al, %rax #11.12
ret #11.12
推荐阅读
- javascript - 如何更改上传按钮上的文本?
- mysql - 尝试连接 MYSQL 容器时出现错误 2013
- sql - SQL错误-如何检索带有字母和数字的记录
- flutter - 该参数的值不能为“null”,因为它在 dart 中的类型,任何解决方案都值得赞赏
- c++ - 链表中的潜在内存泄漏
- angular - 无法在 Java Spring Boot / Angular 应用程序中获取 cookie
- r - 添加带有数据框长度的年份列
- c++ - 如何读入c++ stringstream的第三个字
- python - pyautogui.click() 在特定站点的网络浏览器中不起作用
- html - 如何让 div 垂直位于左侧 div 的右侧?