众所周知,以一种跨步方式访问内存最有利于性能。
在以下情况下
- 我必须访问一个内存区域才能阅读,
- 我必须访问另一个区域进行写作,并且
- 我只能以一种跨步方式访问两个区域之一,
我应该更喜欢阅读 stride one 还是写作 stride one?
一个简单而具体的例子是类似 BLAS 的复制和置换操作,如 y := P x
。置换矩阵 P
完全由某个置换向量 q(i)
定义。它有一个对应的逆置换向量qinv(i)
。可以将所需的循环编码为 y[qinv(i)] = x[i]
或 y[i]=x[q(i)]
其中前者从 x
读取步幅一,后者写入到 y
步幅一。
理想情况下,始终可以对这两种可能性进行编码,在有代表性的条件下对其进行分析,然后选择更快的版本。假设您只能编写一个版本 - 根据现代内存架构的行为,您总是期望哪种访问模式更快?在线程环境中工作会改变您的 react 吗?
最佳答案
访问模式,您将其命名为“writes stride one” (y[i]=x[q(i)]
),通常更快。
如果内存被缓存并且您的数据片段小于缓存行,则此访问模式需要更少的内存带宽。
现代处理器通常具有比存储单元更多的加载执行单元。下一个名为 Haswell 的英特尔架构仅支持 GATHER 指令,而 SCATTER 尚未在他们的计划中。这一切也有利于“写大步”的模式。
在线程环境中工作不会改变这一点。
关于performance - 我应该更喜欢跨一次内存访问来读取还是写入?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9020905/