C ++ new是64字节对齐的,等于缓存行大小

时间:2012-08-10 09:29:39

标签: c++ caching pointers

  

可能重复:
  Is there any guarantee of alignment of address return by C++'s new operation?

在此程序中,我打印 new 返回的每个地址,用于未签名的字符。然后最后将它们向后删除。

#include "stdafx.h"
#include<stdlib.h>
void func();

int main()
{
    int i=10;
    while(i-->0)printf("loaded %i \n", (new unsigned char));
    getchar();
    unsigned char *p=new unsigned char;printf("last pointer loaded %i \n", p);
    i=10;
    while(i-->0)delete (p-=64);
    getchar();
    p+=640;
    delete p;//nearly forgot to delete this ^^
    return 0;
}

输出:

enter image description here

如您所见,每个 new 都会返回64字节对齐的数据。

问题:这个64字节是等于缓存行大小还是只是编译器的东西?

问题:我应该将结构设置为大多数64字节长吗?

问题:当我更改我的cpu,ram,OS或编译器时,这会有所不同吗?

Pentium-m,VC ++ 2010 express,windows-xp

感谢。

1 个答案:

答案 0 :(得分:2)

当您考虑在大量分配和解除分配之后发生的情况时,堆管理器的实现选择更有意义。

malloc()的调用需要找到一个足够大小的未使用块来分配。 它可能更大(在这种情况下,它可以创建一个带有差异的自由块 - 或者浪费它)。找到最接近块大小的简单策略称为最适合。如果它继续创建新的空闲块,您也可以将其称为最差假

使用后,最适合的方法会导致大量碎片,这些碎片是由不太可能再次分配的小块引起的,并且搜索空闲块的成本变高。

因此,高性能堆管理器不能像这样工作。相反,它们作为各种固定块大小的池分配器运行。虽然投入一些中间体,但是块的权力为2(例如64,128,256,512...)范围的方案也可能是有价值的(例如48,96,192...)。在此方案中,malloc()和{{1这两个操作都是free(),分配中的关键部分是最小的 - 可能是每个池 - 这在多线程环境中很重要。

小分配中的内存浪费比碎片,O(1) alloc \ dealloc复杂性和糟糕的MT性能要小得多。

最小块大小w.r.t.缓存线大小是经典的工程权衡之一,可以肯定的是,微软做了相当多的实验,以O(n)作为最小值。 FWIW,我很确定你会发现现代CPU的缓存行大小比这更大。