我想在C / C ++中为数组动态分配内存块,并且将以高频率访问此数组。所以我希望这个阵列保持芯片,即缓存。如何使用C / C ++中的代码显式执行此操作?
答案 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)
答案 3 :(得分:1)
首先,您必须知道要运行代码的计算机的体系结构。然后你应该检查它有一个指令做那种东西。
实际上大量使用内存会强制缓存控制器将此区域置于缓存中。
有三个优化规则,你可能想先了解它们:) http://c2.com/cgi/wiki?RulesOfOptimization