CPU寄存器的大小

时间:2016-04-30 08:08:48

标签: c cpu-registers

通常最好将CPU寄存器用于其全部容量。 对于便携式代码,它意味着在64位CPU上使用64位算术和存储,在32位CPU上仅使用32位(否则,将在32位模式下模拟64位指令,从而导致毁灭性的表演)。

这意味着通常在编译时检测CPU寄存器的大小是必要的(因为运行时测试很昂贵)。

多年来,我一直使用简单的启发式sizeof(nativeRegisters) == sizeof(size_t)

它适用于很多平台,但它似乎是一个错误的启发式Linux x32:在这种情况下,size_t只有32位,而寄存器仍然可以处理64 -Bits。它会导致一些失去的性能机会(对我的用例很重要)。

即使在这种情况下,我也想正确检测CPU寄存器的可用大小。

我怀疑我可以尝试在特殊情况x32模式下找到一些特定于编译器的宏。但我想知道是否存在更通用的东西,以涵盖更多情况。例如,另一个目标是OpenVMS 64位:那里,本机寄存器大小是64位,但size_t只是32位。

2 个答案:

答案 0 :(得分:6)

没有可靠且可移植的方法来确定C的寄存器大小.C甚至没有"寄存器"的概念。 (register关键字的描述没有提到CPU寄存器。)

但它确实定义了一组整数类型,它们是至少指定大小的最快类型。 <stdint.h>定义uint_fastN_t N = 8,16,32,64。

如果您假设寄存器至少为32位,则uint_fast32_t可能与寄存器的大小相同,为32位或64位。这不是保证。这是标准所说的内容:

  

以下每种类型都指定一个通常的整数类型   在所有至少具有的整数类型中运行最快   指定的宽度。

脚注:

  

不保证指定类型对所有目的都是最快的;   如果实施没有明确的理由选择一种类型   另外,它会简单地选择一些满足的整数类型   签名和宽度要求。

事实上,我建议使用[u]int_fastN_t类型比尝试匹配CPU寄存器大小更清楚地表达您的意图。

如果这对某些目标不起作用,您需要添加一些特例 #if#ifdef指令选择合适的类型。但uint_fast32_t(或uint_fast16_t,如果您想支持16位系统)可能是一个比size_tint更好的起点。

快速实验表明,如果我使用gcc -mx32进行编译,uint_fast16_tuint_fast32_t都是32位。在没有-mx32(在我的x86_64系统上)编译时,它们都是64位。这意味着,至少对于gcc,uint_fastN_t类型不要做你想做的事。您需要x32的特例代码。 (可以说gcc 应该在x32模式下使用uint_fastN_t的64位类型。我只是posted this question询问这个问题。)

This question询问如何在预处理器中检测x32环境。 gcc没有直接的方法来确定这一点,但我刚刚发布an answer建议使用__x86_64__SIZE_MAX宏。

答案 1 :(得分:-1)

因此,英特尔过去常常提供他们打印的组件和架构手册,并发送给任何想要它们的开发人员。我打印了最后一套。但他们仍然以pdf格式免费提供这项令人难以置信的服务。 you want to click the link -- Combined Volume Set of Intel® 64 and IA-32 Architectures Software Developer’s Manuals 这将为您提供CPU,寄存器,大小,用法以及程序集关键字的完整列表以及它们如何在每个处理器系列上使用的详细信息。

享受阅读