我们试图使用intel clflush指令在用户空间刷新linux中进程的缓存内容。
我们创建了一个非常简单的c程序,它首先访问一个大数组,然后调用clflush来刷新整个数组的虚拟地址空间。我们测量clflush刷新整个数组所需的延迟。程序中数组的大小是一个输入,我们将输入从1MB变为40MB,步长为2MB。
根据我们的理解,clflush应该刷新缓存中的内容。因此,我们希望看到刷新整个阵列的延迟首先根据阵列的大小线性增加,然后在阵列大小大于20MB(即我们程序的LLC大小)后,延迟应该停止增加。
然而,如图所示,实验结果相当令人惊讶。阵列大小大于20MB后,延迟不会停止增加。
我们想知道clflush是否可能在clflush从缓存中刷新地址之前引入地址,如果地址还不在缓存中?
我们还试图在“英特尔软件开发人员手册”中搜索,但没有找到任何解释,说明如果缓存中没有地址,clflush将执行什么操作。
下面是我们用来绘制图形的数据。第一列是以KB为单位的数组大小,第二列是以秒为单位刷新整个数组的延迟。
任何建议/建议都非常感谢。
[修改]
前面的代码是不必要的。clflush可以在用户空间中更容易地完成,尽管它具有类似的性能。所以我删除了混乱的代码以避免混淆。
SCENARIO=Read Only
1024,.00158601000000000000
3072,.00299244000000000000
5120,.00464945000000000000
7168,.00630479000000000000
9216,.00796194000000000000
11264,.00961576000000000000
13312,.01126760000000000000
15360,.01300500000000000000
17408,.01480760000000000000
19456,.01696180000000000000
21504,.01968410000000000000
23552,.02300760000000000000
25600,.02634970000000000000
27648,.02990350000000000000
29696,.03403090000000000000
31744,.03749210000000000000
33792,.04092470000000000000
35840,.04438390000000000000
37888,.04780050000000000000
39936,.05163220000000000000
SCENARIO=Read and Write
1024,.00200558000000000000
3072,.00488687000000000000
5120,.00775943000000000000
7168,.01064760000000000000
9216,.01352920000000000000
11264,.01641430000000000000
13312,.01929260000000000000
15360,.02217750000000000000
17408,.02516330000000000000
19456,.02837180000000000000
21504,.03183180000000000000
23552,.03509240000000000000
25600,.03845220000000000000
27648,.04178440000000000000
29696,.04519920000000000000
31744,.04858340000000000000
33792,.05197220000000000000
35840,.05526950000000000000
37888,.05865630000000000000
39936,.06202170000000000000
最佳答案
你想看看Skylake的新优化指南,英特尔推出了另一个版本的clflush,叫做clflush_opt,它是弱序的,在你的场景中会表现得更好。
参见此处第7.5.7节-http://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-optimization-manual.pdf
一般来说,clflushopt的吞吐量高于clflush,
因为clflushopt对一组较小的
如上文和第7.5.6节所述的存储器通信量。这个
clflushopt的吞吐量也会有所不同。使用clflushopt时,
刷新修改后的缓存线将比
以非修改状态刷新缓存线。clflushopt将提供
对于任何一致性中的缓存线来说,与clflush相比都有性能优势
国家。clflushopt更适合冲洗大型缓冲区(例如
大于许多kbytes),则将comp分配给clflush。单螺纹
应用程序,使用clflushopt刷新缓冲区的大小可能高达9倍
比使用CLFLUSH和Skylake芯片结构更好。
本节还解释了刷新已修改数据的速度较慢,这显然是由于写回惩罚所致。
对于不断增加的延迟,您是否正在测量在地址范围内遍历并刷新每一行所需的总时间?在这种情况下,即使数组大小超过llc大小,也会线性地依赖于数组大小。即使没有行,clflush也必须由执行引擎和内存单元进行处理,并为每一行查找整个缓存层次结构,即使它不存在。