如何分配内存块并将其放入Cache中?

时间:2013-04-21 15:17:39

标签: c++ c caching memory

我想在C / C ++中为数组动态分配内存块,并且将以高频率访问此数组。所以我希望这个阵列保持芯片,即缓存。如何使用C / C ++中的代码显式执行此操作?

4 个答案:

答案 0 :(得分:3)

没有标准的C ++语言功能允许您这样做。

根据您的编译器和CPU,您可以在asm块中使用特定于arch的CPU指令:

T* p = new T(...);
size_t n = sizeof(T);
asm {
    "CACHE n bytes at address p"
}

...或者执行此操作的一些内置编译器函数(“内在”)。

您需要查阅CPU手册和/或编译器手册。

例如,x86 CPU有一组以PREFETCH开头的指令。

另一个例子是,GCC有一个名为__builtin_prefetch的函数。见GCC Data Prefetch Support

答案 1 :(得分:3)

我将尝试从一个不同的角度回答这个问题。你真的需要这样做吗?即使这是一种方法,它还值得吗?想象一下,有一个“魔术”void * malloc_and_lock_in_cache(int cacheLevel)函数。你将如何处理这些数据。如果它是一个应用程序仅限于while(1)循环与单线程的随机数组访问,无论如何由于优化和CPU架构,你将有这样的行为。如果您考虑更多真实世界的解决方案,您始终拥有围绕访问的逻辑。例如,锁定多线程,某些条件等。问题 - 你的应用程序算法的其余部分是如此完美,只剩下要做的就是在缓存中分配数组。

所有其他访问/排序/查找功能都是最先进的逻辑,无法检查而不是在尝试覆盖CPU优化时获得非常有限的性能反冲。

您是否考虑在原始硬件上运行没有任何操作系统的应用程序,因此您不应该关心分配如何影响操作系统行为,其余应用程序在运行?

如果您的应用程序将在虚拟机或XEN等环境中运行,会发生什么。?

我记得15-18年前一个类似的热门话题,关于物理内存使用和磁盘缓存实用程序。事实上,像MS-DOS smartdrive或类似工具这样的工具真的非常有用,并且可以加速很多事情。 Usenet充满了“调整建议”和性能分析,例如直写/回写设置。

特别是如果您的DOS应用程序正在处理大量数据并实现了一些内存交换逻辑(我说的是时间,然后4MB RAM是奢侈的),这大部分都是戏剧性的,从一个角度来看,你需要尽可能多的内存可以,但从另一个角度来看,你需要交换,所以你实际上需要交换,但交换通过缓存等。

但接下来发生了什么。我们有VM386模式,磁盘缓存/内存交换集成到操作系统,谁更关心调整smartdrive / ramdisks等事情。一般情况下,分配尽可能多的“VM”然后实现自己的voodoo算法来交换物理内存块(尽管此功能仍在WinAPI中)。

所以我真的建议把精力集中在算法和应用程序设计上,而不是尝试使用一些非常低级别的功能,结果确实无法预测,直到你不开发一些新的微内核操作系统。

答案 2 :(得分:2)

我认为你不能。首先,哪个缓存? L3,L2,L1?您可以prefetchalign这样它的访问权限会更加优化,然后您可以定期查询它,也可以让它保持原状而不是LRU,但是您无法让它保持原状在缓存中。

答案 3 :(得分:1)

首先,您必须知道要运行代码的计算机的体系结构。然后你应该检查它有一个指令做那种东西。

实际上大量使用内存会强制缓存控制器将此区域置于缓存中。

有三个优化规则,你可能想先了解它们:) http://c2.com/cgi/wiki?RulesOfOptimization