C ++caching感知编程

有没有一种方法在C ++来确定CPU的caching大小? 我有一个algorithm处理大量的数据,我想把这些数据分解成块,使它们适合caching。 这可能吗? 你可以给我任何其他暗示编程高速caching(特别是在multithreading/多核数据处理方面)的提示吗?

谢谢!

这是我的另一个问题的答案的副本,但在这里:

这里有一篇关于克里斯特·爱立信(第一次世界大战I / II / III)的关于caching/内存优化的非常好的论文的链接 。

这已经过了两三年了,但仍然非常相关。

根据“ 每个程序员应该知道什么内存 ”,Ulrich Drepper可以在Linux上执行以下操作:

一旦我们有内存需求的公式,我们可以将其与caching大小进行比较。 如前所述,caching可能与多个其他内核共享。 目前{当然肯定会有更好的方法!}没有硬编码知识的唯一方法是通过/ sys文件系统获得正确的信息。 在表5.2中,我们看到了内核公布的关于硬件的内容。 一个程序必须find目录:

/sys/devices/system/cpu/cpu*/cache 

这列在第6节:程序员可以做什么 。

他还介绍了图6.5中的一个简短testing,如果您无法从OS获取该testing,则可以使用该testing来确定L1Dcaching大小。

在他的论文中我还碰到了另外一件事情: sysconf(_SC_LEVEL2_CACHE_SIZE)是Linux上的一个系统调用,它应该返回L2高速caching的大小,尽pipe它似乎没有被很好的logging。

C ++本身并不关心CPUcaching,所以不支持查询语言内置的caching大小。 如果您正在开发Windows,那么可以使用GetLogicalProcessorInformation()函数来查询有关CPUcaching的信息。

预分配一个大数组。 然后按顺序访问每个元素并logging每个访问的时间。 理想情况下,发生caching未命中时,访问时间会有所跳跃。 然后你可以计算你的L1caching。 它可能不工作,但值得尝试。

读取cpu(x86)的cpuid,然后通过查找表来确定caching大小。 该表格必须填入cpu的制造商在其编程手册中发布的caching大小。

根据你想要做什么,你也可以把它留给一些图书馆。 由于您提到了多核处理,您可能需要查看一下英特尔线程构build模块 。

TBB包括caching感知内存分配器。 更具体地说,检查cache_aligned_allocator (在参考文档中,我找不到任何直接链接)。

有趣的是,我之前写了一个程序来做这个(虽然在C语言中,但是我相信在C ++代码中很容易)。

http://github.com/wowus/CacheLineDetection/blob/master/Cache%20Line%20Detection/cache.c

get_cache_line函数是一个有趣的函数,它返回arrays访问时序数据最大峰值之前的位置。 它正确地猜到了我的机器! 如果还有其他的东西,它可以帮助你制造自己的东西。

这是基于这篇文章,原来引起我的兴趣: http : //igoro.com/archive/gallery-of-processor-cache-effects/

你可以看到这个线程: http : //software.intel.com/en-us/forums/topic/296674

简短的回答是在另一个线程:

在现代IA-32硬件上,高速caching行大小为64.值128是Intel Netburst微体系结构(如Intel Pentium D)的遗产,其中64字节的行被配对成128字节的扇区。 当扇区中的一条线被取出时,硬件也会自动取出扇区中的另一条线。 所以从虚假的共享angular度来看,Netburst处理器的有效行大小是128字节。 ( http://software.intel.com/zh-cn/forums/topic/292721

IIRC,GCC有一个__builtin_prefetch提示。

http://gcc.gnu.org/onlinedocs/gcc-3.3.6/gcc/Other-Builtins.html

有一个很好的部分。 基本上,它表明:

 __builtin_prefetch (&array[i + LookAhead], rw, locality); 

其中rw是0(准备读取)或1(准备写入)值, locality使用数字0-3,其中0不是局部性,3是非常强的局部性。

两者都是可选的。 预测将是outlook的元素数量。 如果内存访问是100个周期,展开的循环是两个周期,LookAhead可以设置为50或51。

caching通常会做正确的事情。 对于普通程序员来说,唯一真正的担心就是错误的共享,而且在运行时无法处理,因为它需要编译器指令。