在 C 中以 64 位平台为目标时,对数组引用使用 64 位变量是否更好?
When targeting 64-bit platforms in C, is it better to use 64-bit variables for array references?
我正在查看我编写的代码片段的汇编,并注意到指示的 movsxd
操作仅在 ret
变量为 32 位时出现。如果ret
为64位,则直接使用:mov BYTE PTR [rdi+rbp+86], al
.
; 861 : _BitScanForward(&depth, subject);
movsx edx, dx
; 862 : qry_args->lo_refs[++ret] = (BYTE)depth;
inc ebp // ret is in ebp
bsf ecx, edx
movsxd rax, ebp // convert 32-bit ebp to 64-bit rax
; 865 : subject ^= (1 << depth);
; 866 : nulls_mask.lo |= (1 << depth);
movsx r9d, r9w
btc edx, ecx
bts r9d, ecx
mov BYTE PTR [rax+rbx+86], cl // 64-bit rax used by mov
由于 mov
op 在 64 位模式下需要 64 位寄存器,因此对我来说,任何用于引用内存的变量(例如数组引用)理想情况下都应该是 64 位的。
但是,我知道在不超过 2^^31 次迭代的循环中简单地使用 int
是很常见的。我们是否真的应该使用 long long
(int64
) 作为 64 位代码的最佳实践?对此有何评论?
除了这里显示的内容之外,我没有费心测试它。
Ps。这不是微优化问题。这是形式的问题。对我来说,使用编译器使用的类型是有意义的。
信息:我正在使用 VS 2016 进行编译并启用最大优化。
对数组索引使用 size_t
类型。它足够大以容纳数组索引。通常它在 64 位平台上为 64 位,在 32 位平台上为 32 位。
见
在您的情况下使用 long long
通常不是一个好主意。下一个阅读您的代码的开发人员会认为要么代码需要处理大数,要么认为原来的程序员不知道他在做什么。
最好使用 size_t
,表示变量应该能够处理任何数组大小,或 int
,表示它是具有正常范围要求的通用变量。
我应该选择什么整数类型?
int 用于普通整数变量。这是您应该使用的类型,除非有理由选择其他类型。 int
具有平台开发人员选择的大小,因为它是一个很好的使用大小(无论出于何种原因,但通常是该平台上范围、内存消耗和性能之间的良好权衡)
char 用于字符串和二进制数据。如果你打算使用二元运算符(尤其是移位运算符),你应该使用 unsigned char。
size_t 用于array/memory大小、数组索引等
其他 int 大小(short、long、long long、固定大小)是根据需要使用。固定大小通常用于在不同系统之间交换的数据。 long/short 通常在标准函数的 return 值具有相应大小时使用。 long long 在需要存储大数字时使用,但对于非常大的整数,您需要 BigInt 库。
我正在查看我编写的代码片段的汇编,并注意到指示的 movsxd
操作仅在 ret
变量为 32 位时出现。如果ret
为64位,则直接使用:mov BYTE PTR [rdi+rbp+86], al
.
; 861 : _BitScanForward(&depth, subject);
movsx edx, dx
; 862 : qry_args->lo_refs[++ret] = (BYTE)depth;
inc ebp // ret is in ebp
bsf ecx, edx
movsxd rax, ebp // convert 32-bit ebp to 64-bit rax
; 865 : subject ^= (1 << depth);
; 866 : nulls_mask.lo |= (1 << depth);
movsx r9d, r9w
btc edx, ecx
bts r9d, ecx
mov BYTE PTR [rax+rbx+86], cl // 64-bit rax used by mov
由于 mov
op 在 64 位模式下需要 64 位寄存器,因此对我来说,任何用于引用内存的变量(例如数组引用)理想情况下都应该是 64 位的。
但是,我知道在不超过 2^^31 次迭代的循环中简单地使用 int
是很常见的。我们是否真的应该使用 long long
(int64
) 作为 64 位代码的最佳实践?对此有何评论?
除了这里显示的内容之外,我没有费心测试它。
Ps。这不是微优化问题。这是形式的问题。对我来说,使用编译器使用的类型是有意义的。
信息:我正在使用 VS 2016 进行编译并启用最大优化。
对数组索引使用 size_t
类型。它足够大以容纳数组索引。通常它在 64 位平台上为 64 位,在 32 位平台上为 32 位。
见
在您的情况下使用 long long
通常不是一个好主意。下一个阅读您的代码的开发人员会认为要么代码需要处理大数,要么认为原来的程序员不知道他在做什么。
最好使用 size_t
,表示变量应该能够处理任何数组大小,或 int
,表示它是具有正常范围要求的通用变量。
我应该选择什么整数类型?
int 用于普通整数变量。这是您应该使用的类型,除非有理由选择其他类型。 int
具有平台开发人员选择的大小,因为它是一个很好的使用大小(无论出于何种原因,但通常是该平台上范围、内存消耗和性能之间的良好权衡)
char 用于字符串和二进制数据。如果你打算使用二元运算符(尤其是移位运算符),你应该使用 unsigned char。
size_t 用于array/memory大小、数组索引等
其他 int 大小(short、long、long long、固定大小)是根据需要使用。固定大小通常用于在不同系统之间交换的数据。 long/short 通常在标准函数的 return 值具有相应大小时使用。 long long 在需要存储大数字时使用,但对于非常大的整数,您需要 BigInt 库。