performance - 我应该更喜欢跨一次内存访问来读取还是写入?

标签 performance optimization memory matrix blas

众所周知,以一种跨步方式访问内存最有利于性能。

在以下情况下

  • 我必须访问一个内存区域才能阅读,
  • 我必须访问另一个区域进行写作,并且
  • 我只能以一种跨步方式访问两个区域之一,

我应该更喜欢阅读 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/

相关文章:

c++ - 有效地处理调用一百万次的 C/C++ 函数

performance - dart:是否可以缓存或重新创建在重复函数中创建的对象?

mysql针对大量数据的优化

internet-explorer - IE 8 丢弃内存页?

performance - Spark : Explicit caching can interfere with Catalyst optimizer's ability to optimize some queries?

sql - BigQuery 中的线索和分析功能

c - 当我们不知道可用内存的大小时,如何实现伙伴分配器?

java - DLFileEntry在内存中的大小

c++ - 复制一张 map 有多贵?

java - (Java) ArrayList<obj> 中 add(obj o) 方法的内部工作