在C ++中是否有一种方法可以确定CPU的缓存大小?我有一个处理大量数据的算法,我想将这些数据分成适合缓存的块。这可能吗? 您能给我关于编写具有缓存大小意识(特别是关于多线程/多核数据处理方面)的程序的其他提示吗?
谢谢!
在C ++中是否有一种方法可以确定CPU的缓存大小?我有一个处理大量数据的算法,我想将这些数据分成适合缓存的块。这可能吗? 您能给我关于编写具有缓存大小意识(特别是关于多线程/多核数据处理方面)的程序的其他提示吗?
谢谢!
这在第6节:程序员可以做什么中列出。Once we have a formula for the memory requirement we can compare it with the cache size. As mentioned before, the cache might be shared with multiple other cores. Currently {There definitely will sometime soon be a better way!} the only way to get correct information without hardcoding knowledge is through the /sys filesystem. In Table 5.2 we have seen the what the kernel publishes about the hardware. A program has to find the directory:
/sys/devices/system/cpu/cpu*/cache
sysconf(_SC_LEVEL2_CACHE_SIZE)
是一个系统调用,应该返回L2缓存的大小,尽管它似乎没有很好的文档记录。C++本身不涉及CPU缓存,因此语言本身没有支持查询缓存大小的功能。如果你正在开发Windows平台下的应用程序,可以使用GetLogicalProcessorInformation()函数来查询有关CPU缓存的信息。
预先分配一个大数组。然后按顺序访问每个元素并记录每次访问的时间。理想情况下,当缓存未命中时,访问时间会有所增加。然后您可以计算出您的L1缓存。这可能不起作用,但值得一试。
读取CPU(x86)的CPUID,然后通过查找表确定缓存大小。该表必须填充CPU制造商在其编程手册中公布的缓存大小。
CPUID
具有“子标识”功能,可用于查询支持查询的每个CPU上的缓存大小/关联性/行大小,请参见http://en.wikipedia.org/wiki/CPUID#EAX.3D80000006h:_Extended_L2_Cache_Features。 - FrankH.根据您所需的操作,您也可以将其留给一些库。由于您提到多核处理,您可能需要查看Intel Threading Building Blocks。
TBB包括缓存感知内存分配器。更具体地说,请检查cache_aligned_allocator
(在参考文档中,我找不到任何直接链接)。
有趣的是,我曾经写过一个程序来完成这个任务(用的是C语言,但我相信很容易将其融入C ++代码中)。
http://github.com/wowus/CacheLineDetection/blob/master/Cache%20Line%20Detection/cache.c
get_cache_line函数是有趣的函数,它返回数组访问时间数据中最大峰值之前的位置。在我的机器上它猜对了!如果需要,它可以帮助你编写自己的代码。__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,其中零表示没有局部性,3表示非常强的局部性。
两者都是可选的。 LookAhead将是要向前查看的元素数。 如果内存访问需要100个周期,并且展开的循环相隔两个周期,则LookAhead可以设置为50或51。
缓存通常会做正确的事情。对于普通程序员唯一真正担心的是虚假共享,而你无法在运行时处理它,因为它需要编译器指令。