Performance 随机存储器写入比随机存储器读取慢?

Performance 随机存储器写入比随机存储器读取慢?,performance,x86-64,cpu-cache,memory-bandwidth,Performance,X86 64,Cpu Cache,Memory Bandwidth,我试图计算顺序/随机内存读/写的内存访问时间。代码如下: #包括 #包括 #包括 #包括 #包括 #定义打印执行时间(消息、代码)\ 做{\ 结构时间值t1,t2\ 双倍过去\ gettimeofday(&t1,NULL)\ 做{\ 代码\ }而(0)\ gettimeofday(&t2,NULL)\ 经过时间=(t2.tv_秒-t1.tv_秒)*1000.0\ 经过+=(t2.tv_usec-t1.tv_usec)/1000.0\ printf(消息“时间:%f ms\n”,已过)\ }而(0

我试图计算顺序/随机内存读/写的内存访问时间。代码如下:

#包括
#包括
#包括
#包括
#包括
#定义打印执行时间(消息、代码)\
做{\
结构时间值t1,t2\
双倍过去\
gettimeofday(&t1,NULL)\
做{\
代码\
}而(0)\
gettimeofday(&t2,NULL)\
经过时间=(t2.tv_秒-t1.tv_秒)*1000.0\
经过+=(t2.tv_usec-t1.tv_usec)/1000.0\
printf(消息“时间:%f ms\n”,已过)\
}而(0);
const int RUNS=20;

const int N=(1听起来很正常。所有x86-64 CPU(以及大多数其他现代CPU)都使用写回/写分配缓存,因此写操作在提交到缓存之前需要一次读取,最终需要一次写回

使用
-O0
防止优化

由于您在所有本地人身上都使用了
register
,因此这是很少有一次这样做不会使基准变得毫无意义

不过,您可以在阵列上使用
volatile
,以确保这些访问中的每一个都按顺序进行,但如何实现这一点则由优化器决定


我可以肯定地说,seqR的内存带宽是
(20*)((1)您使用什么处理器来运行实验?在我看来,
数据\u p[N]
可以在所有四个函数中访问。您可能想要分配N+1
int
s。谢谢,应该是
N+1
。我使用的是Intel Xeon E5-2695 v4 Broadwell。@zingdle:哦。很多核心Xeon对于单线程内存带宽和四核桌面来说都是出了名的差。尽管如此,4GB/s仍然低于我的预期,所以我选择了我认为你是CPU受限(不是内存)在顺序函数中。请参见@PeterCordes Yes,看起来原始代码受CPU限制。我将数组更改为
volatile
,删除
寄存器
,并使用
O3
重新编译。程序集告诉我它使用一些
xmm
寄存器进行优化,但所花费的时间与以前大致相同。如果我忽略
pos=(pos+i)&N;
并使用
数据[i]访问数组
,花费了一半的时间。但是,我不能像以前那样直接比较随机/顺序内存访问时间。@HadiBrais:同意,这就是我在回答:P中这样说的原因,但保持它可能有助于控制seq和rnd循环中指令计数之间的差异。我从这个精彩的回答中学到了很多,谢谢!我只是想比较顺序/随机访问之间的性能差异,这样就有了冗余的
寄存器
&N
O0
。但是我仍然不确定为什么顺序写入比读取稍快,因为它也使用回写/写分配。@zingdle:
寄存器
如果你是e将使用
-O0
进行编译。这是
register
关键字有用的一次。使用GCC,它将停止变量保存在内存中,并将存储转发存储/重新加载延迟放入循环携带的依赖链中。(看看生成的asm;循环结构可能仍然是垃圾,但至少它没有在内存中保留循环变量。)@zingdle:我认为顺序写入速度更快,因为存储缓冲区可以帮助隐藏偶尔出现的气泡。正如我所说,您的代码在实际内存/缓存带宽方面远未达到瓶颈,因此硬件预取到二级缓存可以轻松跟上。(除非您的CPU陈旧)。您只会在页面边界处遇到暂停。加载必须在从无序后端退出之前完成,但存储必须在提交到L1d之前退出。(存储缓冲区将缓存与推测性执行隔离)。我在Haswell上运行了代码。数字接近OP显示的数字(在Broadwell E5上),除了观察值在许多运行中都不成立外,即,
seqR
/
rndR
不一定比
seqW
/
rndW
快或慢。在许多运行中,差异在1%以内,但有时会稍大一些。我想你是对的。顺序循环可能是管道绑定的(非缓存或内存绑定)和随机循环似乎至少由一级(
L1D_PEND_MISS.FB_FULL
)的填充缓冲区数量绑定。在这两种情况下,实现的BW都远小于最大单线程BW。
seqR time: 2538.010000 ms
seqW time: 2394.991000 ms
rndR time: 40625.169000 ms
rndW time: 46184.652000 ms
seqR time: 2411.038000 ms
seqW time: 2309.115000 ms
rndR time: 41575.063000 ms
rndW time: 46206.275000 ms