虽然我已经阅读了关于这方面的movntdqa指令,但已经想出了一种表达内存范围不可缓存或读取数据的干净方法,以免污染缓存。 我想从gcc做到这一点。我的主要目标是交换到大型阵列中的随机位置。希望通过避免缓存来加速此操作,因为数据恢复非常少。
答案 0 :(得分:7)
我认为你所描述的是Memory Type Range Registers。您可以使用/proc/mttr
/ ioctl(2)
在Linux下控制这些内容(如果可用且您是用户0),请参阅here。由于它适用于物理地址范围,我认为您将很难以合理的方式使用它。
更好的方法是查看编译器内在函数GCC provides并找到一个或多个表达您意图的内容。看看Ulrich Drepper关于“每个程序员应该了解内存的内容”的系列文章,特别是part 5,它涉及绕过缓存。看起来_mm_prefetch(ptr, _MM_HINT_NTA)
可能适合您的需求。
与性能一样 - 测量,测量,测量。 Drepper的系列文章详细介绍了如何完成这项工作(part 7)以及代码示例和其他策略,以加快代码的内存性能。
答案 1 :(得分:2)
来自user786653的所有好建议;尤其是Ulrich Drepper的文章。我要补充一下:
是否未缓存,VM HW将不得不在TLB中查找页面信息,TLB的容量有限。不要低估TLB颠簸对随机访问性能的影响。如果您还没有,请参阅the results here,了解为什么您真的希望使用 huge pages 来获取阵列数据,而不是那些小小的4K默认值(可以追溯到日期) “640K对任何人都应该足够”)。当然,如果你说的是真正庞大的阵列甚至比一个2MB页面的TLB都可以参考,即使这样也无济于事。
你对'nt'指令有什么看法(例如_mm_stream_ps
内在的)?我不相信宣布未缓存的页面会比适当使用那些更好的性能,而且它们比替代品更容易使用。不过,看到相反的证据会非常有兴趣。