我想在C/C++中为一个数组动态分配一个内存块,这个数组会被高频访问。所以我希望这个数组留在芯片上,即在Cache中。如何使用 C/C++ 中的代码显式执行此操作?
4 回答
我将尝试从不同的角度回答这个问题。你真的需要这样做吗。即使这是一种方法,它值得吗?想象有一个“神奇”的 void * malloc_and_lock_in_cache(int cacheLevel) 函数。你将如何处理这些数据。如果它是一个仅限于 while (1) 循环并从单线程访问随机数组的应用程序,那么由于优化和 CPU 架构,您无论如何都会有这样的行为。如果您考虑更多现实世界的解决方案,您总是有关于访问的逻辑。例如锁定多线程,某些条件等。问题 - 你的应用程序算法的其余部分是否非常完美,只剩下要做的就是在缓存中分配数组。
是否所有其他访问/排序/查找功能都是最先进的逻辑,无法审查,而是获得非常有限的性能回扣,试图覆盖 CPU 优化。
此外,您是否考虑在没有任何操作系统的情况下在原始硬件上运行您的应用程序,因此您不应该关心您的分配将如何影响操作系统行为,其余的应用程序运行?
如果您的应用程序将在虚拟机或 XEN 等环境中运行,会发生什么?
我还记得 15 到 18 年前一个类似的流行主题,关于物理内存使用和磁盘缓存实用程序。确实,像 MS-DOS smartdrive 或类似实用程序这样的工具非常有用,并且可以大大加快速度。Usenet 充满了诸如直写/回写设置之类的“调整建议”和性能分析。
尤其是如果您的 DOS 应用程序正在处理大量数据并实现了一些内存交换逻辑(我说的是当时 4MB RAM 是奢侈的),这主要是一场戏剧,从某个角度来看,您需要尽可能多的内存,但是从另一个角度来看,您需要交换,因此您实际上需要交换,但是交换通过缓存等进行。
但接下来发生了什么。我们已经将 VM386 模式、磁盘缓存/内存交换集成到操作系统中,并且谁再关心诸如调整 smartdrive/ramdisk 之类的事情了。一般来说,分配尽可能多的虚拟机然后实现自己的巫毒算法来交换物理内存块是“更便宜”的(尽管这个功能仍然在 WinAPI 中)。
因此,我真的建议将精力集中在算法和应用程序设计上,而不是尝试使用一些非常低级的功能,但结果确实无法预测,直到您不开发一些新的微内核操作系统。
没有标准的 C++ 语言功能允许您执行此操作。
根据您的编译器和 CPU,您可能能够在 asm 块中使用特定于架构的 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 数据预取支持
首先,您必须知道要在其上运行代码的机器的架构是什么。然后你应该检查它有一个指令做那种事情。
实际上大量使用内存将迫使缓存控制器将此区域放入缓存中。
还有优化的三个规则,你可能想先了解它们:) http://c2.com/cgi/wiki?RulesOfOptimization