确定处理器的字大小

时间:2010-02-20 04:11:10

标签: c processor word-size

如何确定CPU的字大小?如果我理解正确,int应该是一个字对吗?我不确定我是否正确。

那么打印sizeof(int)就足以确定处理器的字大小了吗?

10 个答案:

答案 0 :(得分:21)

你对sizeof(int)的假设是不真实的;见this

由于您必须在编译时知道处理器,OS和编译器,因此可以使用编译器提供的预定义architecture/OS/compiler macros来推断字大小。

然而,在更简单和大多数RISC处理器上,字长,总线宽度,寄存器大小和存储器组织通常始终是一个值,对于具有各种大小的浮点寄存器,累加器的更复杂的CISC和DSP架构,情况可能并非如此。 ,总线宽度,高速缓存宽度,通用寄存器等。

当然,这引出了一个问题,为什么你可能需要知道这一点?通常,您将使用适合应用程序的类型,并信任编译器以提供任何优化。如果优化是您认为需要此信息的,那么您最好使用C99 'fast' types。如果您需要优化特定算法,请针对多种类型实施并对其进行分析。

答案 1 :(得分:8)

  

int应该是一个字对吗?

据我了解,这取决于数据大小模型。有关UNIX系统的说明,64-bit and Data Size Neutrality。例如,Linux 32位是ILP32,而Linux 64位是LP64。我不确定Window系统和版本之间的区别,除了我相信所有32位Window系统都是ILP32。

  

如何确定CPU的字大小?

这取决于。你假设哪个版本的C标准。我们在谈论什么平台。这是您尝试制作的编译或运行时间确定。

C标头文件<limits.h>可能会定义WORD_BIT和/或__WORDSIZE

答案 2 :(得分:7)

sizeof(int)并不总是CPU的“字”大小。这里最重要的问题是 为什么 你想知道单词大小....你是否尝试进行某种运行时和CPU特定的优化?

话虽如此,在采用英特尔处理器的Windows上,标称字大小为32位或64位,您可以轻松解决这个问题:

  • 如果您的程序编译为32位,则标称字大小为32位
  • 如果编译了64位程序,则标称字大小为64位。

这个答案听起来很陈旧,但它对第一顺序是正确的。但是有一些重要的微妙之处。即使现代Intel或AMD处理器上的x86寄存器是64位宽;您只能(轻松)在32位程序中使用32位宽度 - 即使您可能正在运行64位操作系统。在Linux和OSX上也是如此。

此外,在大多数现代CPU上,数据总线宽度比标准ALU寄存器(EAX,EBX,ECX等)更宽。这种总线宽度可以变化,有些系统有128位,甚至192位宽的总线。

如果您关注性能,那么您还需要了解L1和L2数据缓存的工作原理。请注意,一些现代CPU具有L3缓存。缓存包括一个称为写缓冲区的单元

答案 3 :(得分:3)

制作一个多次执行某种整数运算的程序,如SAXPY算法的整数版本。针对不同的字大小运行它,范围为8到64位(即从charlong long)。

测量每个版本在运行算法时花费的时间。如果有一个特定版本明显少于其他版本,则该版本使用的字大小可能是您计算机的本机字大小。另一方面,如果有多个版本持续或多或少同一时间,请选择具有更大字长的版本。

请注意,即使使用这种技术,您也可以获得错误的数据:使用Turbo C编译并通过DOS在80386处理器上运行的基准测试将报告字大小为16位,因为编译器不使用32 -bit寄存器用于执行整数aritmetic,但调用内部函数执行每个aritmetic操作的32位版本。

答案 4 :(得分:1)

简而言之:没有好办法。 C数据类型背后的最初想法是int将是最快(本机)整数类型,长期最大等。

然后是来自一个CPU的操作系统,然后移植到本机字大小不同的不同CPU。为了保持源代码的兼容性,一些操作系统打破了这个定义,并将数据类型保持为旧的大小,并添加了新的非标准数据。

也就是说,根据您的实际需要,您可能会在stdint.h中找到一些有用的数据类型,或者出于各种目的在特定于编译器或特定于平台的宏中找到它们。

答案 5 :(得分:0)

在编译时使用:sizeof(void*)

答案 6 :(得分:0)

每个人都知道处理器大小无关紧要的原因。

处理器的大小是One CPU Core的Arthematic Logic Unit(ALU)可以在一个时间点上工作的日期。 CPU Cores的ALU将随时在累加器寄存器上。因此,以位为单位的CPU大小是以位为单位的累加寄存器的大小。

您可以从处理器的数据表中找到累加器的大小,或者编写一个小的汇编语言程序。

请注意,累积器寄存器的有效可用大小可能会根据操作模式(Thumb和ARM模式)在某些处理器(如ARM)中发生变化。这意味着处理器的大小也将根据处理器的模式而改变。

在许多体系结构中,常见的是虚拟地址指针大小和整数大小与累加器大小相同。它只是在不同的处理器操作中利用累加器寄存器,但这不是一个硬性规则。

答案 7 :(得分:0)

许多人认为内存是字节数组。但是CPU对此有另一种看法。这与内存粒度有关。根据体系结构,将有2、4、8、16甚至32字节的内存粒度。内存粒度和地址对齐对软件的性能,稳定性和正确性有很大影响。考虑4字节的粒度和未对齐的内存访问以读取4字节。在这种情况下,每次读取(如果地址增加1个字节,则为75%)将再执行两条读取指令,再执行两次移位操作,最后再执行一条按位指令以获取最终结果,这是性能下降的原因。进一步的原子操作可能会受到影响,因为它们必须不可分割。其他副作用包括高速缓存,同步协议,CPU内部总线流量,CPU写入缓冲区以及您可能还会想到的其他问题。可以在循环缓冲区上运行实际测试,以查看结果如何不同。来自不同制造商的CPU,基于型号,具有不同的寄存器,这些寄存器将用于常规和特定操作。例如,现代CPU具有128位寄存器的扩展。因此,字长不仅与操作类型有关,而且与内存粒度有关。字大小和地址对齐是必须注意的野兽。市场上有一些不关心地址对齐的CPU,如果提供了地址,则将其忽略。猜猜会发生什么?

答案 8 :(得分:0)

正如其他人所指出的,您对计算这个值有什么兴趣?有很多变数。

sizeof(int) != sizeof(word)。至少为了在 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,如果 arch 仍然存在,我可能是错的,我认为没有人必须处理,也不再存在近/远指针,所以如果你使用 c/cpp/c#,sizeof(void*)和 Unsafe.SizeOf{IntPtr}() 足以确定您的最大“字”大小,我认为以合规的跨平台方式,如果有人可以纠正,请这样做!此外,c/cpp 中固有类型的大小在大小定义上很模糊。

C data type sizes - Wikipedia

答案 9 :(得分:0)

“另外,C 类型long 的大小等于word 大小,而int 类型的大小有时小于word 大小。例如, 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;
}