【发布时间】:2017-05-30 21:29:55
【问题描述】:
根据https://software.intel.com/sites/landingpage/IntrinsicsGuide
prefetcht0、prefetcht1、prefetcht2 和 prefetchnta
从内存中获取包含地址 p 的数据行到由位置提示 i 指定的缓存层次结构中的位置。
我确信“数据行”对于熟悉上下文的人来说是显而易见的,但对我来说却是个谜。如果我提供指向某些数据的指针以进行预取,那么将提取的数量是多少? 4B? 64B? 1KB?
如果我打算稍后从该地址读取 32B 并且它只预取 16B,我应该使用偏移量预取多次吗?
【问题讨论】:
-
你有我称之为 fetch line 和 cache line 的东西,它们是两个不同的东西,一些处理器(特别是带有管道的处理器)会在一次 fetch 中获取一些像 32 或 64 字节的块,由于总线更复杂,需要多次握手来移动数据,因此更多、对齐、数据更有效,并且您可以更好地填充管道。高速缓存行与高速缓存和主/慢内存之间的类似传输大小有关。并且通常更大。但是对于什么大小没有规定,这取决于每个实现。
-
基于一些关于此的网络搜索,预取对更新的处理器几乎没有或没有好处,因为更新的处理器上的硬件预取做得很好,除非你可以提前预取实际需要数据,即使在这种情况下,最终循环也可能赶上内存带宽限制。在 Pentium 4 时代,预取更有用。SO 上有一个关于 prefetching 的先前线程。
-
@rcgldr 我想说它仍然具有相当大的影响。我正在优化一个受到随机 I/O 严重瓶颈的算法,除了多线程之外,我尝试在单个线程中解决算法的多个实例,但最终在性能方面基本相同。向混合中添加预取给了我约 30% 的性能提升,这是在 ml64 中的沙桥处理器上
-
@user81993 - 您的体验与其他人提到的不同。在这个500+ line assembly code 用于高度优化的 CRC16 生成(或 CRC32,仅更改常量),一次读取 128 个字节,不使用预取指令,如果您的程序是随机 I/O 绑定的,那么内存如何预取帮助?每次读取之前是否对缓冲区进行了预取?
-
@rcgldr 由于线程中的单独实例彼此无关,因此我可以为下一次循环迭代计算每个实例所需的数据地址,为 all 发出预取命令,然后继续一次解决一个。我的理论是,随着它越走越远,所需数据就越有可能已经在缓存中,因此它不必等待这些数据。我在每个线程执行 8 个实例时获得了最好的结果,之后我似乎遇到了某种形式的另一面墙,因为额外的实例并没有提高速度。
标签: caching assembly memory intrinsics