哪种方式更好地获得64位整数中较低的32位
Which way is better to get lower 32 bits of a 64 bits integer
我发现在一些答案中,他们建议使用
lower = (some_var << 32) >> 32;
但我测试了一下,发现以下更快:
lower = some_var & 0xffffffff;
那么,哪一个更好呢?前者在某些情况下更安全,还是在编译器优化后更快?
用&
掩蔽更好:
&
对于有符号和无符号some_var
是可靠的,而将负数右移会产生实现定义的结果:
E1>>E2的值是E1右移E2位的位置。[…]如果E1具有带符号的类型和负值,则生成的值是实现定义的。
- 在我所知道的每一个CPU(Z80、6502C、x86、68000、UltraSparc)上,逐位AND是一条CPU指令,需要一个时钟周期。。。它不太可能比你提到的移位方法慢或占用更多字节的机器代码,尽管编译器可能会将其优化为逐位AND
掩蔽的一个缺点是,很容易意外地出现7或9个F
错误,而32
中的拼写错误是显而易见的:不过,还有其他方法可以生成掩蔽值,例如(1LL<<32)-1
,或者时髦但优雅的uint32_t(-1)
。
当然,如果lower
是uint32_t
和some_var
uint64_t
,您可以让转换是隐式的,所以优化器甚至不需要意识到按位and可以在赋值前删除,但这可能会给您一个编译器警告,您可以使其静音。…
uint32_t lower = static_cast<uint32_t>(some_var);
当分配给另一个uint64_t
时,或者当掩码不是针对所有32个最低有效位时,掩码主要是有用的。
使用AND的掩码更好,因为它不依赖于值的有符号性。
但取低32位的最有效方法是将其分配给32位变量。
uint64_t u = 0x1122334455667788;
uint32_t n;
n = static_cast<uint32_t>(u); // 0x55667788
与位"与"的区别在于,CPU只占用较低的部分,而不进行任何逻辑运算。
如果你有一个32位的CPU,它只会忽略存储在第二个寄存器或内存位置的上限值。
如果您有一个64位CPU,它有一条将32位值扩展(无符号)为64位值的指令。
一个好的优化器会在这两种情况下生成相同的代码。对我来说,这是最直接的方法:lower = some_var & 0xffffffff;
其他形式可能会产生不必要的偏移。
有时,当我想绝对确保编译器不会把事情搞砸时,我会使用并集来重叠变量。
例如:
typedef union {
int64 QWORD;
int32 DWORD[2];
} overlapper64;
overlapper someVariable;
然后访问它作为:
someVariable.QWORD;
int32 myVar32 = someVariable.DWORD[0];
根据平台/编译器的不同,重叠发生的顺序可能会有所不同。一定要在您的特定平台上进行测试。在C中,我使用了一堆特定于平台的#ifdef来自动控制订单。
根据其他人的说法,使用第二个选项可能会更快,因为如果不优化,第一个选项将实现为2条cpu指令,而第二个选择是一条cpu指令。这可能是您观察到使用第二个选项可以提高性能的原因。
我认为两者都一样好。然而,使用逐位运算符将是一种更好的方法(不确定是否存在任何性能差异),正如标准所说:
6.5.7位移位运算符
4 E1<lt;E2为E1左移位的E2位位置;腾空的位用零填充。如果E1无符号类型结果是E1×2E2,降模1大于最大值可在结果类型中表示。如果E1具有带符号类型且为非负值,并且E1×2E2是可表示的在结果类型中,则为结果值;否则行为未定义。
- 如何忽略32位整数中的特定位
- 检测 32 位整数溢出
- 将 64 位整数中的每个其他位与 32 位整数进行比较
- 对 32 位整数进行哈希处理比对 3 个 16 位整数的哈希进行按位运算慢?
- 将 32 位大端有符号整数转换为有符号小端整数
- 如何将 32 位无符号整数分配给包含 32 位的位字段
- SSE 整数 2^n 的 2 次方,对于没有 AVX2 的 32 位整数
- 32 位整数缩放,无溢出
- 获取两个无符号整数 C++ 乘积的高 32 位的有效方法
- Visual C 32位整数从文件到8位字符到文件 - 程序在某些整数上崩溃
- 有没有办法让32位C 编译器遵循16位整数促销规则
- C++:如何将 32 位数据转换为有符号整数
- 我们是否需要担心 32 位或 64 位整数,或者我们只使用 'int'
- 将 32 位浮点数和不强制转换的 32 位整数与双精度进行比较,当其中一个值可能太大而无法完全适合另一种类型时
- 优化 32 位架构上的可移植 128 位整数移位
- 尝试从另一个过程读取32位整数时,ReadProcessMemory崩溃了
- 如何在AVX2中从32位转换为16位未签名的整数
- AVX __M256I整数部门用于签名的32位元素
- 将浮点数 32 位变量类型转换为无符号整数 32 位时进行了哪些位级更改
- 左移一个整数32位