alignmentcaching行并知道caching行大小

为了防止错误共享,我想要将数组的每个元素alignment一个caching行。 所以首先我需要知道一个caching行的大小,所以我分配的每个元素的字节数量。 其次我想要数组的开始alignment一个caching线。

我正在使用Linux和8核x86平台。 首先,我如何findcaching行大小。 其次,我如何alignment到C中的caching行。我正在使用gcc编译器。

所以这个结构将会是例子,假设一个高速caching行大小为64。

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

依此类推,假设0-63与caching线alignment。

要知道尺寸,你需要使用处理器的文档来查找它,afaik没有编程的方法来做到这一点。 然而,从积极的angular度来看,大多数caching行都是基于intels标准的标准尺寸。 在x86高速caching行上有64个字节,但是为了防止错误共享,你需要遵循你所针对的处理器的指导原则(intel在它的基于netburst的处理器上有一些特别的注释),一般你需要alignment到64字节(英特尔声明,你也应该避免交叉16个字节的边界)。

要在C或C ++中执行此操作,需要使用标准的aligned_alloc函数或编译器特定的说明符之一,如__attribute__((align(64)))__declspec(align(64)) 。 要在结构中的成员之间进行填充以将其拆分到不同的caching行中,您需要插入一个足够大的成员以将其与下一个64字节的bounderyalignment

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

 $ getconf LEVEL1_DCACHE_LINESIZE 64 

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

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

在运行时,可以使用sysconf(_SC_LEVEL1_DCACHE_LINESIZE)来获取L1caching大小。

另一个简单的方法是只捕获/ proc / cpuinfo:

cat / proc / cpuinfo | grep cache_alignment

posix_memalignvalloc可用于将分配的内存与高速caching行alignment。

没有完全可移植的方式来获得caching线的大小。 但是如果你使用的是x86 / 64,你可以调用cpuid指令来获得关于caching的所有知识 – 包括大小,caching行大小,多less级别等等。

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

(向下滚动一下,页面是关于SIMD的,但它有一个获取caching行的部分。)

至于调整你的数据结构,也没有完全可移植的方法来做到这一点。 GCC和VS10有不同的方法来指定结构的alignment。 一种“破解”它的方法是用未使用的variables填充你的结构,直到它匹配你想要的alignment。

为了alignment你的malloc(),所有的主stream编译器也都有相应的malloc函数。

如果有人对如何在C ++中轻松做到这一点感到好奇,我已经构build了一个具有CacheAligned<T>类的库,该库处理确定caching行大小以及T对象的alignment方式,通过调用.Ref()在你的CacheAligned<T>对象上。 你也可以使用Aligned<typename T, size_t Alignment>如果你事先知道caching行的大小,或者只是想坚持64(字节)的常见值。

https://github.com/NickStrupat/Aligned