Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/151.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 是否需要显式对齐?_C++_Memory_Alignment_Padding - Fatal编程技术网

C++ 是否需要显式对齐?

C++ 是否需要显式对齐?,c++,memory,alignment,padding,C++,Memory,Alignment,Padding,经过一些阅读,我了解到编译器已经对结构或类进行了填充,以便可以在其自然对齐的边界上访问每个成员。那么,在什么情况下,编码器需要进行显式对齐以获得更好的性能呢?我的问题由此产生: 英特尔64和IA-32体系结构优化参考手册: For best performance, align data as follows: Align 8-bit data at any address. Align 16-bit data to be contained within an aligned 4-byte w

经过一些阅读,我了解到编译器已经对结构或类进行了填充,以便可以在其自然对齐的边界上访问每个成员。那么,在什么情况下,编码器需要进行显式对齐以获得更好的性能呢?我的问题由此产生:

英特尔64和IA-32体系结构优化参考手册:

For best performance, align data as follows:
Align 8-bit data at any address.
Align 16-bit data to be contained within an aligned 4-byte word.
Align 32-bit data so that its base address is a multiple of four.
Align 64-bit data so that its base address is a multiple of eight.
Align 80-bit data so that its base address is a multiple of sixteen.
Align 128-bit data so that its base address is a multiple of sixteen.
假设我有一个结构:

struct A
{
    int a;
    int b;
    int c;
}
// size = 12;
// aligned on boundary of: 4
通过创建类型A的数组,即使我什么也不做,它也会正确对齐。那么,遵循指南并使对齐更牢固有什么意义呢

是因为缓存线分裂吗?假设缓存线是64字节。当第6次访问数组中的对象时,字节从61开始到72,这会减慢程序的速度


顺便说一句,标准库中是否有一个宏,它通过返回std::size\u t的值来告诉我基于运行机器的对齐要求?

当您想要显式对齐时,我唯一能做的事情就是直接将结构之间的数据复制/转换为字符*,以便在某种类型的二进制协议中进行序列化

此处意外的填充可能会导致协议的远程用户出现问题

在伪代码中:

struct Data PACKED
{
  char code[3];
  int val;
};

Data data = { "AB", 24 };
char buf[20];
memcpy(buf, data, sizeof(data));
send (buf, sizeof(data);

现在,如果我们的协议需要3个八位字节的代码,后跟4个八位字节的整数值,那么如果我们使用上述代码,我们将遇到问题。因为填充会给我们带来问题。实现这一点的唯一方法是对上面的结构进行打包(allignment 1)

语言中确实有一个工具(它不是宏,也不是来自标准库)来告诉您对象或类型的对齐方式。它是(另请参见:)

回答您的问题:一般来说,您不应该关心对齐。编译器将为您处理这些数据,通常/大多数情况下,它比您更了解如何对齐数据

您需要处理对齐的唯一情况(请参阅)是在编写一些代码时,这些代码允许一些可能不太对齐的数据类型作为一些可能更对齐的数据类型的备份存储


在引擎盖下执行此操作的示例有和。在标准库中也有明确的用于创建这样一个后备存储的设施,即,./P>> p>让我直接回答您的问题:不,不需要明确地在C++中对齐数据以实现性能。 任何合适的编译器都会正确地对齐底层系统的数据

如果您有以下情况,问题就会出现(上面的变化):

 struct 
 {
     int w ;
     char x ;
     int y ;
     char z ;
 } 
这说明了两个常见的结构对齐问题

(1) 编译器很可能会在x和z之后插入(2)3个对齐字节。如果x后面没有填充,则y未对齐。如果在z之后没有填充,那么数组中的w和x将不对齐

您在手册中阅读的说明是针对汇编语言程序员和编译器编写者的

当数据未对齐时,在某些系统(不是Intel)上会导致异常,而在其他系统上则需要多个处理器周期来获取和写入数据

通过创建类型A的数组,即使我什么也不做,它也会正确对齐。那么,遵循指南并使对齐更牢固有什么意义呢

ABI只描述如何使用它定义的数据元素。本指南不适用于您的
结构

是因为缓存线分裂吗?假设缓存线是64字节。当第6次访问数组中的对象时,字节从61开始到72,这会减慢程序的速度

缓存问题可能会出现任何一种情况。如果您的算法随机访问数组并触及所有
a
b
c
,则将整个结构对齐到16字节边界将提高性能,因为从内存中获取
a
b
c
中的任何一个都会获取其他两个。但是,如果只使用线性访问或随机访问只接触其中一个成员,16字节对齐将浪费缓存容量和内存带宽,从而降低性能

详尽的分析其实并不必要。你可以试着看看什么能提高性能。(或添加一个伪成员,C++11之前的版本。)

顺便问一下,标准库中是否有宏通过返回
std::size\t
值来告诉我基于运行机器的对齐要求


C++11(和C11)有一个操作符。

我想首先要记住的是,这是一个微观优化。正确对齐结构所获得的速度(通常)非常小,而要对齐结构所需的代码膨胀和非标准装饰在维护方面通常非常昂贵。无论何时尝试优化这些内容,都需要检查SOA是否优于AOS。根据您的CPU,未对齐数据类型对性能的影响可能非常严重。在某些架构上,它甚至会导致硬崩溃。您能举个例子吗?谢谢结构包装不是标准C++的一部分。