1

我有一台 64 位 i7 机器。假设我为 n 个 32 位整数分配内存。分配中实际使用了多少物理寄存器:n 还是 n/2?

我尝试编写以下简单程序来找出答案。

#include <iostream>
#include <cstdlib>

using namespace std;

int main (int argc, char *argv[]) {
    int a[4];
    cout << &a[0] << "\t" << &a[3] << endl;
    cin.ignore (1);
    return 0;
} // End main ()

输出是:

0018FA04        0018FA10

他们似乎比他们应该的距离更远。为什么地址不是 04 和 07?这是否意味着系统实际上分配了四个(或更多)整数,而不是将四个 32 位整数打包到两个 64 位寄存器中?

在此先感谢您的帮助。

4

4 回答 4

9

每个 int 为 32 位(4 个字节)。其中 3 个占 12 个字节。0x0018FA10 - 0x0018FA04 = 12。

于 2012-04-05T05:29:02.233 回答
2

这是布局:

a[0]; // 0018FA04 00 00 00 00
a[1]; // 0018FA08 00 00 00 00
a[2]; // 0018FA0C 00 00 00 00
a[3]; // 0018FA10 00 00 00 00

它与寄存器大小无关。

于 2012-04-05T05:32:05.810 回答
2

我有一台 64 位 i7 机器。假设我为 n 个 32 位整数分配内存。分配中实际使用了多少物理寄存器:n 还是 n/2?

64 位 i7 机器是 x86_64 架构。

在这个架构上,一个 32 位整数数组将被完全打包分配,这意味着数组的大小将是 4n 字节。

如果物理寄存器是指机器字,并且您认为机器字在 x86_64 上是 64 位的,那么它将使用 n/2 个机器字。

我不会使用物理寄存器这个词,这可能会与 cpu 寄存器混淆,这不是分配数组的地方(除非非常小并且优化器是积极的)。

他们似乎比他们应该的距离更远。为什么地址不是 04 和 07?这是否意味着系统实际上分配了四个(或更多)整数,而不是将四个 32 位整数打包到两个 64 位寄存器中?

因为体系结构是字节寻址的而不是字寻址的。正如预期的那样,它们相隔 12个字节。

于 2012-04-05T06:03:39.270 回答
1

首先,用于sizeof(int)了解系统上的int宽度。然后sizeof(int) * N应该给出你的数组占用的字符数。除非存在我称之为奇怪的系统(因为奇怪的对齐或填充我认为已经对齐的数据......编辑虽然 64 位系统可能更喜欢对齐 32 位数据填充它们与额外的 32 位,这听起来几乎合乎逻辑)它应该是sizeof(int) * 4 == sizeof(a)提供的具体示例中的内容。当然,数组a很可能没有保存在任何 CPU 寄存器中,而是在main函数的堆栈上。

编辑

例如,

#include <iostream>
#include <cstdlib>

using namespace std;

int main (int argc, char *argv[]) {
    int a[4];
    cout << &a[0] << "\t" << &a[3] << endl;
    cout << sizeof(int) << " " << sizeof(a) << endl;
    cin.ignore (1);
    return 0;
} // End main ()

在使用 Sun CC -m64 编译的 sparc 机器上,给出了

ffffffff7ffff748        ffffffff7ffff754
4 16
于 2012-04-05T05:36:09.920 回答