alignas和alignof关键字有什么用?

问题描述 投票:0回答:2

我无法理解

alignas
alignof
关键字的用途,并且我不太确定我完全理解什么是对齐。

据我了解,如果内存地址可被n整除,则它与n个字节对齐,也就是说,可以通过一次计算“n”个字节来获得它(从0?或某个默认值?)。此外,在变量声明前面添加

alignas
关键字时,指定存储变量的地址如何对齐,而
alignof
返回变量的地址如何对齐。

但是,我不确定这是对对齐或

alignof
/
alignas
关键字的正确理解 - 请纠正我的任何错误点。我也不明白这些关键字有什么用,所以如果有人能指出他们的目的是什么,我将不胜感激。

c++11 alignment
2个回答
8
投票

一些特殊类型必须以比平常更多的字节对齐 - 例如,矩阵必须在 x86 上以 16 字节对齐,才能最有效地复制到 GPU。 SSE 向量类型也可以这样表现。因此,如果您想创建容器类型,那么您必须知道您要包含或分配的类型的对齐要求。


0
投票

据我了解,如果内存地址可以被n整除,则它与n个字节对齐,也就是说,可以通过一次计算“n”个字节来获得它(从0?或某个默认值?)。

是的,它通常等于 0,因为它是硬件对齐,类似于(旧)硬盘柱面的对齐(请参阅柱面磁头扇区)。好吧,我不确定我对圆柱体的看法是否正确;我对硬件不感兴趣。

我从未使用过

alignas
,但显然它对于优化与某些硬件的交互很有用。例如,虽然它不是针对 RAM 的,但在
gcc
的手册页中,您可以看到
-falign-*
优化选项,并解释了它们的用途:对齐输出中的一些代码,以便 CPU 可以一次获取更多指令.

对于常见的标量类型,通常会让

sizeof(your_type)
等于
alignof(your_type)
,这是为了优化。但对于复合类型(数组或结构体),该值会有所不同,通常等于成员之一所需的最大对齐。

不考虑比 RAM 更多的硬件,这对于某些通用接口可能很有用。当然,像

malloc()
这样的分配函数总是给你一个对任何类型都方便的地址,也就是说,与
max_align_t
对齐,它的
alignof
通常为16(根据
long double
的要求)。但今年,我参与了一个项目,该项目仅使用一个
malloc()
来分配矩阵 和指向矩阵每一行的 指针,在同一个块中,例如对于类型为
int * *
的变量。因此,该块应首先包含
int *
指针的空间,然后包含
int
值的空间。因为(在普通系统上)
alignof(int *) % alignof(int) == 0
,这种情况下是没有问题的。但在 32 位架构上,例如,它会因
double
int64_t
而失败,因为指针是 4 字节长,并且值需要 8 对齐。因此必须使用
alignof
来确定正确的值。开始为值(当然,填充必须添加到分配的大小中)。就我而言,这还没有完成,这不是问题,因为该程序仅在 64 位架构上进行了测试,并且没有使用
long double
或类似的东西。但我已经修复了,所以程序肯定可以在32位机器上运行。

alignof
的一个更有趣的用途可以是:定义用于处理泛型类型的泛型函数,例如泛型链表,就像我在当前正在开发的一个小型宏库中所做的那样。像往常一样,它使用一个包含项目数据和指向下一个项目的指针的结构。宏允许轻松定义任何类型的链表类型,然后处理此类列表的函数是宏,它调用采用
void *
指针以及对齐和大小信息的函数。您可以在此处 (.h)此处 (.c) 查看代码。头文件中的代码可能有点恶心,但这就是为 C 制作强大 API 的代价。here提供了一个使用示例 - 请注意,它使用后缀为
T
的 C99 兼容宏,其中需要一直指定类型,我还没有为较新的宏编写测试(它使用 C23 的
typeof
,它长期以来一直是 GNU 扩展)。

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