问题描述 投票:1回答:1

我知道这都是具体的实现,但为了举例说明,我们假设对于某台现代计算机来说。

int 占用了一整个WORD

short 占了半个WORD

短的实际会不会占用更少的内存,还是只会存储在一个WORD的前半部分,后半部分有未使用的内存?CC++编译器是否会尝试将两个或更多较小的变量打包到一个WORD中,还是会一直浪费这个空间?

c++ c memory memory-alignment
1个回答
2
投票

这在很大程度上取决于用法。

  1. 你通常可以强制编译器对空间进行优化。
  2. 当对象被对齐到一个内存边界时,它的大小是其大小的倍数时,会被更优化地访问(在大多数架构上)。因此,编译器可能会注入空间以获得更好的对齐。这通常发生在要求不同大小的对象彼此相邻的时候。
  3. 编译器是 允许重新安排结构中变量的顺序(如果它们在同一个privatepublicprotected部分)。
  4. 我不相信局部堆栈框架中的变量顺序有任何要求。所以编译器应该能够对局部变量进行优化打包,并优化使用所有可用空间(甚至有可能为POD变量重用空间,或者如果能把空间保留在寄存器中就永远不用空间)。

但如果你的结构是使用相同大小的对象。

struct X
{
    short      var1;
    short      var2;
}

那么很有可能上述结构中不会有填充物(不保证,但极有可能没有填充物)。

因为上面的第3点。如果你想帮助你的编译器对一个结构进行最佳打包,那么对编译器来说,将你的成员从最大到最小的顺序排列肯定会更容易,因为这使得不需要填充的打包更容易(但标准并没有对填充提出任何要求)。

// if we assume sizeof(int) == 8
struct Y
{
    char      x;  // 1 byte;
                  // Compiler will (prob) insert 7 bytes of padding here.
                  // to make sure that y is on an 8 byte boundry
                  // for most effecient reads.
    int       y;
    char      z;  // 1 byte
                  // Compiler will (prob) insert 7 bytes of padding here.
                  // to make sure that the whole structure has a size
                  // that is a multiple of 8 (the largest object)
                  // This allows for optimal packing of arrays of type
                  // Y.
};

如果你这样安排对象,编译器仍然可以实现最佳的打包和快速访问。

struct Y
{
    int      y;
    char     x;
    char     z;
    // probably add 6 bytes of padding.
    // So that we get optimal access to objects in an array.
};

为了举例说明,我们假设对于某台现代计算机来说。

如果我们假设在普通的标准架构机器上使用一个现代的好的编译器,比如clang或者g++。即使我们假设不对速度进行优化。

短的实际上会不会占用更少的内存

是的,现代编译器会尽可能地打包对象,可能只使用所需的内存。现代编译器会尽可能的打包对象,可能只使用所需的内存。注意:大多数编译器默认会对速度进行优化,所以会保持最佳的对齐速度,所以会在必要时进行填充(如果一个结构中不能重新排序的对象有不同的大小)。

还是会只存储在WORD的前半部分,后半部分有未使用的内存?

不太可能,除非有一些编译器必须维护的要求。比如结构的顺序。

CC++编译器会不会尝试将两个或更多的小变量打包到一个WORD中呢?

是的,一直都是 所有的时间。默认为通常。1 针对速度进行优化。2 针对大小进行优化(并不总是相互排斥)。你也可以强制现代编译器优化空间和打包结构,而不需要填充。

或者说这些空间会一直被浪费吗?

不太可能。

© www.soinside.com 2019 - 2024. All rights reserved.