Ela*_*iss 143 c++ optimization
我总是假设在做(a % 256)优化器时自然会使用有效的按位操作,就像我写的那样(a & 0xFF).
在编译器资源管理器gcc-6.2(-O3)上进行测试时:
// Type your code here, or load an example.
int mod(int num) {
return num % 256;
}
mod(int):
mov edx, edi
sar edx, 31
shr edx, 24
lea eax, [rdi+rdx]
movzx eax, al
sub eax, edx
ret
Run Code Online (Sandbox Code Playgroud)
在尝试其他代码时:
// Type your code here, or load an example.
int mod(int num) {
return num & 0xFF;
}
mod(int):
movzx eax, dil
ret
Run Code Online (Sandbox Code Playgroud)
好像我完全错过了一些东西.有任何想法吗?
gna*_*729 228
这是不一样的.尝试num = -79,您将从两个操作中获得不同的结果.(-79) % 256 = -79,虽然(-79) & 0xff是一些正数.
使用unsigned int,操作是相同的,代码可能是相同的.
PS-有人评论道
它们不应该相同,
a % b定义为a - b * floor (a / b).
这不是它在C,C++,Objective-C中定义的方式(即问题中的代码将编译的所有语言).
Ral*_*zky 53
-1 % 256产率-1,而不是255它是-1 & 0xFF.因此,优化将是不正确的.
C++的惯例(a/b)*b + a%b == a似乎很自然.a/b始终返回没有小数部分的算术结果(截断为0).因此,a%b具有与a0 相同的符号.
除法-1/256产生0因此-1%256必须是-1为了满足上述条件((-1%256)*256 + -1%256 == -1).这显然是不同的-1&0xFF这是0xFF.因此,编译器无法优化您想要的方式.
从N4606开始,C++标准[expr.mul§4]中的相关部分指出:
对于积分操作数,
/运算符产生代数商,丢弃任何小数部分; 如果商a/b在结果类型中可表示,(a/b)*b + a%b则等于a[...].
但是,使用unsigned类型,优化将是完全正确的,满足上述约定:
unsigned(-1)%256 == 0xFF
Run Code Online (Sandbox Code Playgroud)
另请参见本.
这可以在不同的编程语言中处理得非常不同,因为您可以在维基百科上查找.
Bat*_*eba 50
从C++ 11开始,num % 256如果num是负数则必须是非正数.
因此位模式将取决于系统上已签名类型的实现:对于负第一个参数,结果不是最低有效8位的提取.
如果num在你的情况下,那将是另一回事unsigned:这些天我几乎期望编译器进行你引用的优化.
| 归档时间: |
|
| 查看次数: |
15576 次 |
| 最近记录: |