3

最近,我在最近的一次采访中遇到了一个字符串操作问题,并被要求优化性能。我不得不使用迭代器在 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 位的,但是在这样的设备上内存大小会受到限制。所以我想知道整数和寄存器大小之间是否存在架构微调决定。

4

6 回答 6

4

C++ 标准没有指定 int 的大小。(它说sizeof(char) == 1,和sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long)

所以不必寄存器大小有关系。完全符合 C++ 的实现可以在您的 PC 上使用 32 位寄存器为您提供 256 字节整数。但这将是低效的。

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

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

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

于 2009-07-03T11:56:50.993 回答
3

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

于 2009-07-03T11:02:50.407 回答
2

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

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

例子

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

然后,使用声明的别名。

于 2009-07-03T10:52:41.333 回答
2

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

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

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

于 2009-07-03T11:34:38.893 回答
2

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

你不是唯一一个说“我承认这在技术上是一个缺陷,但它并不是真正可利用的”。

于 2009-07-03T13:21:48.513 回答
2

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

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

于 2009-07-03T13:32:25.180 回答