"alignas"和"alignof"关键字用于什么目的?

8
我不太明白关键字alignasalignof的用途,也不确定自己是否完全理解什么是内存对齐。我的理解是,如果一个内存地址可以被n整除,那么它对n字节对齐,也就是说,可以每次以“n”个字节(从0或某个默认值)计数获得该地址。此外,当变量声明前缀为alignas关键字时,指定变量存储的地址应如何对齐,而alignof则返回变量地址对齐方式。但是,我不确定这是否是正确的内存对齐或alignof/alignas关键字的理解,请纠正我任何错误的地方。此外,我也不知道这些关键字的用途是什么,如果有人能指出它们的目的,我将不胜感激。
2个回答

8

一些特殊类型必须按照比通常更多的字节对齐-例如,在x86上,矩阵必须在16字节处对齐,以实现最有效的复制到GPU。SSE向量类型也可以这样行事。因此,如果您想创建容器类型,则必须了解您要包含或分配的类型的对齐要求。


那么关键字只在某些情况下用于提高效率? - user98188
@Keand64:在许多平台和情况下,不正确的对齐是一个错误。x86更加宽容。在一般情况下,您必须尊重UDT所需的对齐方式。 - Puppy

0
据我理解,如果一个内存地址可以被n字节整除,那么它就是按n字节对齐的,也就是说,可以通过每次计数'n'个字节(从0开始?还是某个默认值?)来到达该地址。
是的,通常它与0同余,因为这是一种硬件对齐,类似于(旧式)硬盘上的柱面对齐(参见Cylinder-head-sector)。嗯,我不确定柱面的事情是否正确;我对硬件不太熟悉。
我从未使用过alignas,但显然它在与某些硬件的交互中可以用于优化。例如,虽然它不适用于RAM,但在gcc的man页中,你可以看到-falign-*优化选项,其中解释了它们的目的:将一些代码在输出中对齐,以便CPU可以一次获取更多指令。
通常情况下,对于普通的标量类型,你会发现sizeof(your_type)等于alignof(your_type),这是为了优化。但对于复合类型(数组或结构体),这个值会有所不同,并且通常等于成员中所需的最大对齐方式。

不考虑RAM之外的硬件,这对于一些通用数据管理功能可能很有用。当然,像malloc()这样的分配函数总是会给你一个方便任何类型的地址,也就是对齐到max_align_t,它通常具有16的alignof(如long double所需)。但今年,我参与了一个项目,该项目仅使用一个malloc()来分配矩阵以及矩阵每行的指针,放在同一个块中,例如对于int * *类型的变量。因此,该块首先包含int *指针的空间,然后是int值的空间。因为(在常见系统上)alignof(int *) % alignof(int) == 0,在这种情况下没有问题。但在32位架构上,如果使用doubleint64_t等类型,将会失败,因为指针长度为4字节,而值需要8字节的对齐。因此,必须使用alignof来确定值的正确起始位置(当然,还必须添加填充到分配的大小中)。在我的情况下,这个问题尚未解决,因为程序只在64位架构上进行了测试,并且没有使用long double或类似类型。但我已经修复了这个问题,所以该程序肯定可以在32位机器上运行。

如果我理解正确的话,alignof(type)等同于offsetof(struct char_and_type, item),如果你有:
struct char_and_type {
    char c;
    type item;
};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接