【问题标题】:Is there a relation between integer and register sizes?整数和寄存器大小之间有关系吗?
【发布时间】:2009-07-03 10:29:04
【问题描述】:

最近,我在最近的一次采访中遇到了一个字符串操作问题,并被要求优化性能。我不得不使用迭代器在 TCHAR 字符之间来回移动(支持 UNICODE - 每个 2 字节)。

没有真正考虑数组长度,我犯了一个错误,没有使用 size_t 而是使用 int 进行迭代。我了解它不合规且不安全。

int i, size = _tcslen(str);    
for(i=0; i<size; i++){
   // code here
}

但是,我们可以分配的最大内存是有限的。如果 int 和寄存器大小之间存在关系,则使用整数可能是安全的。

例如:没有任何虚拟映射工具,我们只能映射 2^register-size 个字节。由于 TCHAR 的长度为 2 个字节,因此是该数字的一半。对于任何将 int 作为 32 位的系统,即使您不使用 int 的无符号版本,这也不会成为问题。有嵌入式背景的人曾经认为 int 是 16 位的,但是在这样的设备上内存大小会受到限制。所以我想知道整数和寄存器大小之间是否存在架构微调决定。

【问题讨论】:

  • 读起来更像是一篇博文,而不是一个问题。
  • 抱歉,我必须提供更多信息才能得到回复。简单地询问整数/寄存器大小并没有同样的意义。
  • burcu- 你能解释一下,使用 int 是如何不安全的。你的意思是说这里可能会导致溢出吗?
  • 不,询问整数和寄存器大小之间是否存在关系将是一个非常清楚的问题。通过将其隐藏在背景中,我实际上必须阅读两遍以确保这实际上是您所要求的。
  • Vivek,是的,我指的是溢出。我试着编辑了一下,但还是很长。

标签: c++ memory integer cpu cpu-registers


【解决方案1】:

C++ 标准没有指定 int 的大小。 (上面写着sizeof(char) == 1sizeof(char) &lt;= sizeof(short) &lt;= sizeof(int) &lt;= sizeof(long)

因此必须与寄存器大小无关。完全符合 C++ 的实现可以在您的 PC 上使用 32 位寄存器为您提供 256 字节整数。但这会是低效的。

所以是的,实际上,int 数据类型的大小通常等于 CPU 通用寄存器的大小,因为这是迄今为止最有效的选择。

如果int 比寄存器大,那么简单的算术运算将需要多条指令,这将是昂贵的。如果它们小于寄存器,则加载和存储寄存器的值将需要程序屏蔽未使用的位,以避免覆盖其他数据。 (这就是为什么int 数据类型通常比short 更有效。)

(某些语言只要求int 为32 位,在这种情况下,显然与寄存器大小无关——除了选择32 位之外,因为它是常见的寄存器大小)

【讨论】:

  • 谢谢,这回答了我的性能导向问题,并表明如果平台选择稳定,使用整数并不是那么愚蠢。
  • int 是寄存器的大小在 16 位和 32 位平台上通常是正确的,但所有 64 位平台(据我所知)都将 int 作为 32 位和 64 位。 (而且它们有 64 位寄存器)。
  • 但是这些 64 位架构通常仍然具有所有 32 位指令,因此没有性能损失。在“纯”64 位架构上,int 可能是 64 位的。也许。不过好点。
【解决方案2】:

严格按照标准,不能保证 int 的大小,更不用说与寄存器大小的关系了。此外,某些架构具有不同大小的寄存器(即:并非 CPU 上的所有寄存器都具有相同大小),并且并不总是只使用一个寄存器来访问内存(例如具有 Segment:Offset 寻址的 DOS)。 尽管如此,在大多数情况下,int 的大小与“常规”寄存器的大小相同,因为它应该是最常用的基本类型,而这正是 CPU 优化运行的原因。

【讨论】:

    【解决方案3】:

    AFAIK,寄存器大小和 int 大小之间没有直接联系。

    但是,由于您知道要为哪个平台编译应用程序,您可以使用所需的大小定义自己的类型别名:

    例子

    #ifdef WIN32 // Types for Win32 target
    #define Int16 short
    #define Int32 int
    // .. etc.
    #elif defined // for another target
    

    然后,使用声明的别名。

    【讨论】:

      【解决方案4】:

      如果我理解正确的话,我并不完全清楚,因为这里混合了一些不同的问题(内存大小、分配、寄存器大小、性能?)。

      我可以说的是(只是标题),在大多数实际处理器上,为了获得最大速度,您应该使用与寄存器大小匹配的整数。原因是,当使用较小的整数时,您具有需要较少内存的优势,但是例如在 x86 架构上,需要额外的转换命令。同样在英特尔上,您也有问题,访问未对齐的(主要是在寄存器大小的边界上)内存会带来一些惩罚。当然,在今天的处理器上,事情甚至更加复杂,因为 CPU 能够并行处理命令。因此,您最终需要对某些架构进行微调。

      所以最好的猜测——在不知道架构的情况下——最快的是,使用寄存器大小的整数,只要你能负担得起内存。

      【讨论】:

        【解决方案5】:

        我没有标准的副本,但我的旧副本C 编程语言 说(第 2.2 节)int 指的是“一个整数,通常反映主机上的整数。”我的C++ 编程语言副本说(第 4.6 节)“int 类型应该被选择为最适合在给定计算机上保存和操作整数。”

        你不是唯一一个说“我承认this is technically a flaw, but it's not really exploitable”的人。

        【讨论】:

          【解决方案6】:

          有不同种类的不同大小的寄存器。重要的是地址寄存器,而不是通用寄存器。如果机器是 64 位的,那么地址寄存器(或它们的某种组合)必须是 64 位的,即使通用寄存器是 32 位的。在这种情况下,编译器可能需要做一些额外的工作才能使用多个通用寄存器实际计算 64 位地址。

          如果您认为硬件制造商从来没有为他们的寄存器做出奇怪的设计选择,那么您可能永远不必处理原始的 8086“real mode”寻址。

          【讨论】:

            猜你喜欢
            • 2017-05-18
            • 1970-01-01
            • 2010-10-16
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-02-04
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多