函数不受主内存约束所需的复杂性是多少?

Mar*_*ayr 7 c c++ performance x86 assembly

我知道如果没有缓存数据,访问主内存的延迟很高.这个问题是关于吞吐量的.

在常规台式PC上永远不受主内存限制的函数所需的复杂性是多少?

我读到了带宽为25-30GB/s的现代RAM(DDR3 RAM,双通道模式).据我所知,现代英特尔处理器的单核可以使用现代SIMD指令集存储每条指令最多32字节.它最多可以运行4*10 ^ 9条指令.如此有效,它可以输出大约120GB/s.给定具有8个线程的处理器,作为最坏情况估计,最大输出量将是大约960GB/s.

处理器最多可以输出可写入RAM的数据的~36倍.是否可以安全地假设每个SIMD存储或加载超过36个周期运行非加载/存储操作的任何函数(或每个常规8个字节存储或加载超过9个周期)将永远不会受到主存储器的约束?由于某些原因,这个估计值是可以显着降低还是太低?

鉴于我有:

X = (x_1, x_2, ..., x_n) // dataset, large enough to make good use of caches
a(x), b(x), c(x, y), d(x) := c(a(x), b(x)) // functions that operate on elements
A(x) := (a(x_1), a(x_2), ..., a(x_n)) // functions that operate on data sets
Run Code Online (Sandbox Code Playgroud)

我正在寻找实施更好(或更糟)的准则

D(X)
Run Code Online (Sandbox Code Playgroud)

C(A(X), B(X))
Run Code Online (Sandbox Code Playgroud)

鉴于第一个实现对缓存和寄存器施加了更大的压力,第二个实现具有更多的加载/存储操作.

(当然,你可以告诉我基准测试的东西,我很好.但有时候,我只是想做一个有根据的猜测,只是重新审视一些东西,当它成为一个问题或后来的瓶颈.)

fwg*_*wgx 1

我认为这很大程度上取决于代码是否以这样的方式编写:CPU可以将下一个数据项预取到缓存中。如果它预取了错误的数据,那么无论您花费多少时间处理当前数据,您仍然会受到内存限制。

如果您有多个线程写入同一地址(它们的数据将位于不同的缓存行),那么即使它已正确预取,如果另一个线程已写入该地址,则必须转储并从 main 重新读取它再次记忆。

总之,我认为在这个级别上推理此类事情是不可能的,这将取决于您所拥有的确切场景。