【发布时间】:2015-07-05 01:43:03
【问题描述】:
假设我必须编写一个 C 或 C++ 计算密集型函数,该函数有 2 个数组作为输入,一个数组作为输出。如果计算使用 2 个输入数组的频率高于它更新输出数组的频率,我最终会遇到输出数组很少被缓存的情况,因为它被逐出以获取 2 个输入数组。
我想为输出数组保留一部分缓存,并以某种方式强制这些行在获取后不会被驱逐,以便始终将部分结果写入缓存。
Update1(output[]) // Output gets cached
DoCompute1(input1[]); // Input 1 gets cached
DoCompute2(input2[]); // Input 2 gets cached
Update2(output[]); // Output is not in the cache anymore and has to get cached again
...
我知道有一些机制可以帮助驱逐:clflush、clevict、_mm_clevict 等。有没有相反的机制?
我正在考虑 3 种可能的解决方案:
- 如果数据已被驱逐,不时使用 _mm_prefetch 取回数据。但是,这可能会产生不必要的流量,而且我需要非常小心何时引入它们;
- 尝试对较小的数据块进行处理。但是,这只有在问题允许的情况下才有效;
- 在可能的情况下禁用硬件预取器以降低不必要的驱逐率。
除此之外,还有什么优雅的解决方案吗?
【问题讨论】:
-
当我遇到类似情况时,偶尔的预取指令已经产生了可衡量的好处。诀窍是对何时保持聪明。
-
通常是这样,尤其是当行已被逐出但如果我对已经在缓存中的行进行预取,它会更新缓存替换算法中的重用距离吗?
-
您确定这会实际上提高性能吗?我建议采取相反的方式:未缓存/非临时/写入组合存储。
-
驱逐控制可能就是您所需要的。如果
input1不在缓存中,那么input2应该适合而不必替换output。
标签: c++ c caching memory-management optimization