如何编写自动处理缓存行对齐的 C/C++ 代码。
假设我们用 c 语言编写一个结构体,其中有 5 个成员,我们希望将此结构体成员与不同硬件 X86 硬件 CPU 中的不同缓存线对齐。
例如,如果我有两台 X86 机器 Machine_1 和 Machine_2。 Machine_1 有 64 字节缓存线,Machine_2 有 32 字节缓存线。 我将如何进行编码,以便每个变量都与 Machine_1 和 Machine_2 的不同缓存行对齐。
struct test_cache_alignment {
int a;
int b;
int c;
int d;
int e;
};
谢谢, 阿布舍克
最佳答案
这主要分为两个独立的问题。
第一个问题是确保整个结构从缓存行边界开始,这取决于结构所在的位置。如果使用 malloc()
为结构分配内存,则需要一个 malloc()
来确保对齐。如果将结构放入全局数据中,则编译器和/或链接器必须确保对齐。如果您有一个结构作为本地数据(在堆栈上),那么编译器必须生成确保对齐的代码。
这只能部分解决。您可以编写自己的 malloc()
或围绕现有 malloc()
编写包装器。您也许能够拥有对齐的特殊部分(而不是使用正常的 .rodata
、.data
和 .bss
部分)并令人信服链接器做正确的事情。您可能无法让编译器生成适当对齐的本地数据。
问题的第二部分是确保结构内成员的偏移量是缓存行大小的倍数。这意味着如果结构作为一个整体对齐,那么结构的成员也将对齐。这可能并不难做到(只要您不介意“稍微不可移植”的代码和痛苦的微观管理)。例如:
#define CACHE_LINE_SIZE 32
struct test_cache_alignment {
int a;
uint8_t padding1[CACHE_LINE_SIZE - sizeof(int)];
int b;
uint8_t padding2[CACHE_LINE_SIZE - sizeof(int)];
int c;
uint8_t padding3[CACHE_LINE_SIZE - sizeof(int)];
int d;
uint8_t padding4[CACHE_LINE_SIZE - sizeof(int)];
int e;
uint8_t padding5[CACHE_LINE_SIZE - sizeof(int)];
};
但是;对于这种特定情况(整数结构),很少想像这样浪费空间。如果没有填充,它将全部适合单个缓存行,并将其分布在多个缓存行中只会增加缓存未命中并降低性能。
我能想到的唯一实际想要使用整个缓存行的情况是减少多 CPU 系统中的错误共享(例如,避免由不同 CPU 修改同一结构的不同成员引起的“缓存行弹跳”)同时)。通常,对于这些情况,您一开始就做错了(例如,最好有单独的局部变量并且根本不使用结构)。
关于c++ - 用 C/C++ 语言编写低延迟代码,自动处理缓存行大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24094119/