用C/ c++语言编写一个低延迟代码,自动处理缓存行大小

Writing a Low latency code in C/ C++ language that automatically take care of cache lines size

本文关键字:代码 延迟 处理 缓存 一个 语言 c++      更新时间:2023-10-16

如何编写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修改同一结构的不同成员在同一时间)。通常在这些情况下,你一开始就做错了一些事情(例如,也许最好有单独的局部变量,根本不使用结构)。