...有效内存“带宽”...在最坏的情况下从主内存到CPU:
存在两种“最差”情形:不使用(未命中)CPU高速缓存的存储器访问和访问太远地址且不能重用开放DRAM行的存储器访问。
RAM缓存
缓存不是RAM的一部分,它是CPU的一部分,并命名 CPU缓存 (上半部分 记忆层次 )。
由于处理的连续地址中的距离很远,因此效率很低。
现代CPU缓存有许多内置 硬件预取器 ,它可以检测几次存储器访问之间的非随机步骤。许多预取器将检测对齐的4千字节(KB)页面内的任何步骤:如果访问地址1,然后地址1 + 256字节,则L1预取程序将开始访问地址1 + 256 * 2,地址1 + 256 * 3等。一些预取程序可能会尝试预测超出4 KB范围。因此,仅使用访问之间的长距离可能是不够的。 (预取者可能被禁用 https://software.intel.com/en-us/articles/disclosure-of-hw-prefetcher-control-on-some-intel-processors )
据我所知,这里重要的是RAM延迟而不是带宽
是的,当RAM访问受延迟限制时,有一些模式。
场景是这样的(假设您使用64位= 8字节值):
您可以使用8字节值;但你应该考虑内存和缓存使用更大的单位。现代DRAM存储器具有64位(8字节)宽的总线(在ECC的情况下为72 + 64 + 8),并且许多事务可能使用几个总线时钟周期(突发预取在 DDR4 SDRAM 使用8n - 8 * 64位。 CPU缓存和内存控制器之间的许多事务也更大,并且大小已满 缓存行 或者作为缓存行的一半。 典型的高速缓存行是64字节 。
you read data at an address make some light weight CPU computation (so that CPU is not the bottleneck) then you read data at new address quite far-away from the first one
此方法不适合现代无序CPU。在当前存储器访问完成之前,CPU可以推测性地重新排序机器命令并开始执行下一存储器访问。
针对cpu缓存和内存延迟的经典测试(来自lmbench的lat_mem_rd http://www.bitmover.com/lmbench/lat_mem_rd.8.html 和许多其他人)使用填充了一些特殊的伪随机指针模式的内存数组;读取延迟的测试就像( https://github.com/foss-for-synopsys-dwc-arc-processors/lmbench/blob/master/src/lat_mem_rd.c#L95 )
char **p = start_pointer; for(i = 0; i < N; i++) { p = (char **)*p; p = (char **)*p; ... // repeated many times to hide loop overhead p = (char **)*p; }
因此,下一个指针的地址存储在存储器中; cpu无法预测下一个地址并以推测方式开始下一次访问,它将等待来自缓存或内存的读取数据。
我想知道吞吐量(以字节为单位)。
它可以以每秒访问量来衡量;对于字节访问,或字访问或8字节访问,将有相似数量的访问/ s,吞吐量(字节/秒)将乘以所使用的单位。
有时会测量类似的价值 - GUPS - 每秒guga更新 (通过测试,读取,更新和写回内存中的数据) 随机访问 。该测试可以使用数百(或数万)PC的计算集群的内存 - 检查GUP / s列 http://icl.cs.utk.edu/hpcc/hpcc_results.cgi?display=combo
假设RAM具有典型的DDR3 13 ns延迟的简单计算产生8 B / 13 ns = 600 MB / s的带宽。但这提出了几点:
RAM有几个延迟(时间) - https://en.wikipedia.org/wiki/Memory_timings
只有当您访问打开的行时,13 ns CAS才有意义。对于随机访问,您通常会访问闭合行,并且会向CAS添加T_RCD延迟。