如何确定 CPU 的字长?如果我理解正确,int
应该是一个词,对吗?我不确定我是否正确。
那么仅打印sizeof(int)
就足以确定我的处理器的字长吗?
您对 sizeof(int) 的假设是不正确的;看到这个。
由于您必须在编译时了解处理器、操作系统和编译器,因此可以使用编译器提供的预定义架构/操作系统/编译器宏来推断字长。
然而,虽然在更简单和大多数 RISC 处理器上,字长、总线宽度、寄存器大小和存储器组织通常始终是一个值,但对于浮点寄存器、累加器、总线宽度等具有各种大小的更复杂的 CISC 和 DSP 架构来说,这可能不是真的,缓存宽度,通用寄存器等。
当然,这引出了一个问题,为什么您可能需要知道这一点?通常,您会使用适合应用程序的类型,并相信编译器会提供任何优化。如果优化是您认为需要此信息的目的,那么使用C99 'fast' types可能会更好。如果您需要优化特定算法,请为多种类型实现它并对其进行分析。
一个 int 应该是一个词吧?
据我了解,这取决于数据大小模型。有关 UNIX Systems, 64-bit and Data Size Neutrality的解释。例如 Linux 32 位是 ILP32,而 Linux 64 位是 LP64。除了我相信所有 32 位 Window 系统都是 ILP32 之外,我不确定 Window 系统和版本之间的区别。
如何确定 CPU 的字长?
那要看。您假设哪个版本的 C 标准。我们在说什么平台。这是您尝试进行的编译或运行时确定。
C 头文件<limits.h>
可以定义WORD_BIT
和/或__WORDSIZE
.
sizeof(int) 并不总是 CPU 的“字”大小。这里最重要的问题是为什么你想知道字长....你是在尝试做某种运行时和 CPU 特定的优化吗?
话虽如此,在配备 Intel 处理器的 Windows 上,标称字长将是 32 位或 64 位,您可以轻松计算出:
这个答案听起来很陈词滥调,但它确实符合第一顺序。但是有一些重要的微妙之处。即使现代 Intel 或 AMD 处理器上的 x86 寄存器是 64 位宽的;您只能(轻松)在 32 位程序中使用它们的 32 位宽度 - 即使您可能正在运行 64 位操作系统。在 Linux 和 OSX 上也是如此。
此外,在大多数现代 CPU 上,数据总线宽度比标准 ALU 寄存器(EAX、EBX、ECX 等)更宽。这个总线宽度可以变化,一些系统有 128 位,甚至 192 位宽的总线。
如果您关心性能,那么您还需要了解 L1 和 L2 数据缓存的工作原理。请注意,一些现代 CPU 具有 L3 缓存。缓存包括一个称为写入缓冲区的单元
编写一个多次执行某种整数运算的程序,例如 SAXPY 算法的整数版本。为不同的字长运行它,从 8 位到 64 位(即从char
到long long
)。
测量每个版本在运行算法时花费的时间。如果有一个特定版本的持续时间明显少于其他版本,则用于该版本的字长可能是您计算机的本机字长。另一方面,如果有几个版本或多或少同时存在,则选择字长较大的版本。
请注意,即使使用这种技术,您也可以获得错误数据:您的基准测试,使用 Turbo C 编译并通过 DOS 在 80386 处理器上运行,将报告字长为 16 位,只是因为编译器不使用 32 位寄存器执行整数算术运算,但调用执行每个算术运算的 32 位版本的内部函数。
“此外,C 类型 long 的大小等于字长,而 int 类型的大小有时小于字长。例如,Alpha 具有 64 位字长。因此,寄存器、指针和 long 类型的长度为 64 位。”
来源:http: //books.msspace.net/mirrorbooks/kerneldevelopment/0672327201/ch19lev1sec2.html
记住这一点,可以执行以下程序来找出您正在使用的机器的字长 -
#include <stdio.h>
int main ()
{
long l;
short s = (8 * sizeof(l));
printf("Word size of this machine is %hi bits\n", s);
return 0;
}
简而言之:没有什么好办法。C 数据类型背后的最初想法是 int 将是最快的(本机)整数类型,long 是最大的类型等。
然后出现了源自一个 CPU 的操作系统,然后被移植到本机字长不同的不同 CPU。为了保持源代码的兼容性,一些操作系统打破了这个定义,将数据类型保持在原来的大小,并添加了新的、非标准的。
也就是说,根据您的实际需要,您可能会在 中找到一些有用的数据类型stdint.h
,或者用于各种用途的特定于编译器或特定于平台的宏。
知道处理器大小的原因可能是什么,这并不重要。
处理器的大小是一个 CPU 核心的算术逻辑单元 (ALU) 在单个时间点可以工作的日期量。CPU 内核的 ALU 将随时在累加器寄存器上。因此,以位为单位的 CPU 的大小就是以位为单位的累加器寄存器的大小。
您可以从处理器的数据表或编写一个小型汇编语言程序中找到累加器的大小。
请注意,在某些处理器(如 ARM)中,累加器寄存器的有效可用大小可能会根据操作模式(Thumb 和 ARM 模式)而改变。这意味着处理器的大小也会根据处理器的模式而改变。
在许多体系结构中,虚拟地址指针大小和整数大小与累加器大小相同。这只是在不同的处理器操作中利用累加器寄存器,但这不是硬性规则。
在编译时使用:sizeof(void*)
许多人认为内存是一个字节数组。但是CPU对此有另一种看法。这与内存粒度有关。根据架构的不同,内存粒度可能有 2、4、8、16 甚至 32 字节。内存粒度和地址对齐对软件的性能、稳定性和正确性有很大影响。考虑 4 字节的粒度和以 4 字节读取的未对齐内存访问。在这种情况下,每次读取,如果地址增加一个字节,则为 75%,需要另外两个读取指令加上两个移位操作,最后是按位指令获得最终结果,这是性能杀手。进一步的原子操作可能会受到影响,因为它们必须是不可分割的。其他副作用是缓存、同步协议、cpu 内部总线流量、cpu 写缓冲区,你猜还有什么。可以在循环缓冲区上运行实际测试以查看结果有何不同。来自不同制造商的 CPU,根据型号,具有不同的寄存器,这些寄存器将用于一般和特定操作。例如,现代 CPU 具有 128 位寄存器的扩展。因此,字长不仅与操作类型有关,还与内存粒度有关。字长和地址对齐是必须小心的野兽。市场上有一些 CPU 不负责地址对齐,如果提供,则简单地忽略它。猜猜会发生什么?字长不仅与操作类型有关,还与内存粒度有关。字长和地址对齐是必须小心的野兽。市场上有一些 CPU 不负责地址对齐,如果提供,则简单地忽略它。猜猜会发生什么?字长不仅与操作类型有关,还与内存粒度有关。字长和地址对齐是必须小心的野兽。市场上有一些 CPU 不负责地址对齐,如果提供,则简单地忽略它。猜猜会发生什么?
正如其他人指出的那样,您对计算这个值有什么兴趣?有很多变数。
sizeof(int)!= sizeof(字)。至少为了 Windows api 世界中的 API 兼容性,字节、字、双字等的大小自创建以来从未改变过。即使处理器字长是指令可以操作的自然大小。例如,在 msvc/cpp/c# 中,sizeof(int) 是四个字节。即使在 64 位编译模式下。Msvc/cpp 具有 __int64,而 c# 具有 Int64/UInt64(非 CLS 兼容)ValueType。win32 API 中也有 WORD DWORD 和 QWORD 的类型定义,从未分别从两个字节、四个字节和八个字节改变。以及 Win32 上的 UINT/INT_PTR 和 c# 上的 UIntPtr/IntPtr 保证足够大以分别表示内存地址和引用类型。AFAIK,如果拱门仍然存在,我可能是错的,我认为没有人需要处理,也不需要,近/远指针不再存在,所以如果你在 c/cpp/c# 上,sizeof(void*) 和 Unsafe.SizeOf{IntPtr}() 就足以确定我认为符合标准的最大“字”大小跨平台方式,如果有人可以纠正,请纠正!此外,c/cpp 中内在类型的大小在大小定义上也很模糊。