c-对齐缓存行并知道缓存行大小

为了防止错误共享,我想将数组的每个元素与高速缓存行对齐。 因此,首先我需要知道高速缓存行的大小,因此我为每个元素分配了一定数量的字节。 其次,我希望数组的开头与缓存行对齐。

我正在使用Linux和8核x86平台。 首先,我如何找到缓存行大小。 其次,如何在C中对齐缓存行。我正在使用gcc编译器。

因此,假设缓存行大小为64,结构将如下所示。

element[0] occupies bytes 0-63
element[1] occupies bytes 64-127
element[2] occupies bytes 128-191

依此类推,假设0-63与高速缓存行对齐。

6个解决方案
79 votes

我正在使用Linux和8核x86平台。 首先,我如何找到缓存行大小。

$ getconf LEVEL1_DCACHE_LINESIZE
64

将值作为宏定义传递给编译器。

$ gcc -DLEVEL1_DCACHE_LINESIZE=`getconf LEVEL1_DCACHE_LINESIZE` ...

在运行时sysconf(_SC_LEVEL1_DCACHE_LINESIZE)可用于获取L1缓存大小。

Maxim Egorushkin answered 2019-11-06T23:24:30Z
33 votes

要知道尺寸,您需要使用处理器的文档进行查找,而afaik尚无编程方法来实现。 从好的方面来说,大多数缓存行都是基于Intel标准的标准大小。 在x86缓存上,行为64字节,但是,为防止错误共享,您需要遵循目标处理器的准则(intel在基于netburst的处理器上有一些特殊说明),通常您需要为此对齐64字节 (英特尔指出,您还应该避免越过16个字节的边界)。

要在C或C ++中执行此操作,需要使用标准aligned_alloc函数或特定于编译器的说明符之一,例如__attribute__((align(64)))__declspec(align(64))。要在结构中的成员之间填充以将其拆分为不同的缓存行,则需要插入大成员 足以使其与下一个64字节边界对齐

Necrolis answered 2019-11-06T23:23:53Z
9 votes

没有完全可移植的方法来获取缓存行大小。 但是,如果您使用的是x86 / 64,则可以调用cpuid指令来获取您需要了解的有关缓存的所有信息-包括大小,缓存行大小,多少个级别等。

[http://softpixel.com/~cwright/programming/simd/cpuid.php]

(向下滚动一点,该页面是关于SIMD的,但是有一部分获取了缓存行。)

至于对齐数据结构,也没有完全可移植的方式来实现。 GCC和VS10具有指定结构对齐方式的不同方法。一种“破解”方法是用未使用的变量填充结构,直到它与所需的对齐方式匹配为止。

为了对齐您的mallocs(),所有主流编译器也都为此目的对齐了malloc函数。

Mysticial answered 2019-11-06T23:25:21Z
9 votes

另一种简单的方法是只添加/ proc / cpuinfo:

猫/ proc / cpuinfo | grep cache_alignment

Francesquini answered 2019-11-06T23:25:52Z
8 votes

posix_memalign或valloc可用于将分配的内存与高速缓存行对齐。

MetallicPriest answered 2019-11-06T23:26:16Z
2 votes

如果有人对如何在C ++中轻松实现此功能感到好奇,我就建立了一个带有CacheAligned<T>类的库,该类可确定高速缓存行的大小以及T对象的对齐方式,可通过在.Ref()对象上调用.Ref()进行引用。 如果您事先知道高速缓存行的大小,或者只是想保留非常常见的值64(字节),也可以使用Aligned<typename T, size_t Alignment>

[https://github.com/NickStrupat/Aligned]

Nick Strupat answered 2019-11-06T23:26:49Z
translate from https://stackoverflow.com:/questions/7281699/aligning-to-cache-line-and-knowing-the-cache-line-size