当前位置:  开发笔记 > 编程语言 > 正文

C++的新操作是否保证地址返回的对齐?

如何解决《C++的新操作是否保证地址返回的对齐?》经验,为你挑选了4个好方法。

大多数有经验的程序员都知道数据对齐对于程序的性能很重要.我看到一些程序员编写的程序分配比他们需要的更大的缓冲区大小,并使用对齐的指针作为开始.我想知道我应该在我的程序中这样做,我不知道是否有任何保证C++的新操作返回的地址对齐.所以我写了一个小程序来测试

for(size_t i = 0; i < 100; ++i) {
    char *p = new char[123];
    if(reinterpret_cast(p) % 4) {
        cout << "*";
        system("pause");
    }
    cout << reinterpret_cast(p) << endl;
}
for(size_t i = 0; i < 100; ++i) {
    short *p = new short[123];
    if(reinterpret_cast(p) % 4) {
        cout << "*";
        system("pause");
    }
    cout << reinterpret_cast(p) << endl;
}
for(size_t i = 0; i < 100; ++i) {
    float *p = new float[123];
    if(reinterpret_cast(p) % 4) {
        cout << "*";
        system("pause");
    }
    cout << reinterpret_cast(p) << endl;
}
system("pause");

我使用的编译器是Visual C++ Express 2008.似乎返回的新操作的所有地址都是对齐的.但我不确定.所以我的问题是:有保证吗?如果他们确实有保证,我不必调整自己,如果没有,我必须.



1> Richard Cord..:

对齐具有以下标准(3.7.3.1/2)的保证:

返回的指针应适当对齐,以便它可以转换为任何完整对象类型的指针,然后用于访问分配的存储中的对象或数组(直到通过调用相应的释放函数显式释放存储) .

编辑:感谢timday为突出一个错误在gcc/glibc的在保证不成立.

编辑2:本的评论突出了一个有趣的边缘案例.对分配例程的要求仅适用于标准提供的那些.如果应用程序有自己的版本,那么结果就没有这样的保证.


@BenVoigt:你有更多细节吗?你是说有保证,但它是在其他地方给出的吗?我有(N3337)草案,在5.3.4/10下它讨论了返回(无符号)char数组的要求,并开始注释:"因为假定分配函数返回指向适当对齐的对象的存储的指针任何基本对齐的类型......".
@Richard:另一件事是你从`new []`获得的最小正确对齐与最佳对齐不同.出于性能原因,您希望某些结构与缓存对齐.因此,即使您更新答案以引用标准的正确部分,它仍然无法解决所提出的问题.此外,一些指令(特别是SSE)*需要*更严格的对齐.

2> user1059432..:

这是一个迟到的答案,但只是为了澄清Linux上的情况 - 在64位系统上,内存总是16字节对齐:

http://www.gnu.org/software/libc/manual/html_node/Aligned-Memory-Blocks.html

由GNU系统中的malloc或realloc返回的块的地址始终是8的倍数(或64位系统上的16).

new运营商调用malloc内部(见./gcc/libstdc++-v3/libsupc++/new_op.cc),因此适用于new为好.

执行malloc这是部分glibc基本上定义 MALLOC_ALIGNMENT2*sizeof(size_t)size_t是32位= 4字节的64位和8字节=上分别X86-32和x86-64系统,.

$ cat ./glibc-2.14/malloc/malloc.c:
...
#ifndef INTERNAL_SIZE_T
#define INTERNAL_SIZE_T size_t
#endif
...
#define SIZE_SZ                (sizeof(INTERNAL_SIZE_T))
...
#ifndef MALLOC_ALIGNMENT
#define MALLOC_ALIGNMENT       (2 * SIZE_SZ)
#endif



3> jheriko..:

顺便提一下,MS文档提到了一些关于malloc/new返回地址的信息,这些地址是16字节对齐的,但是从实验来看并非如此.我碰巧需要一个项目的16字节对齐(以加速具有增强指令集的内存副本),最后我使用编写自己的分配器...



4> mfazekas..:

平台的new / new []运算符将返回具有足够对齐方式的指针,以使其在基本数据类型(double,float等)下表现良好。至少任何明智的C ++编译器+运行时都应该这样做。

如果您对SSE有特殊的对齐要求,那么使用特殊的aligned_malloc函数或自行滚动可能是个好主意。

推荐阅读
我我檬檬我我186
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有