我的核心i7系统的L1缓存大小为32KB,L2缓存大小为256KB,共享L3缓存大小为8MB(在4个核心之间共享)。 我编写了一个程序,我按顺序执行A,B,C部分。 (A)创建一个大的int数组,其大小为L2缓存的4倍,并访问大数组的每个第16个元素(缓存行大小为64B,16 * 4 B = 64B),以确保我的所有数据都加载到L2中。注意大数组(B)的每个元素的访问时间,然后使用clflush从我的数据数组的多个位置手动逐出数据,如clflush(& bigarray [0])... clflush(& bigarray [1024]) 。 (C)再次访问大数组的每个第16个元素,包括在(B)中手动逐出的那些行。
我在访问我的大数组的行之前和之后放了rdtsc()来查找访问时间。我从这个链接clflush() in i3 or i7 processors
知道在i3 / i7机器上使用clflushasm volatile ("cpuid; rdtsc" : "=a" (a), "=d" (d) : : "ebx", "ecx");
在按照预期推出一条线路后,我的访问时间越来越长,以及多个地点的访问时间没有增加。
让我以其他方式解释:
场景1 :在clflush之前和之后访问单个数组元素
场景2 :在clflush之前和之后访问多个数组元素
第2步 -
for all i {
clflush( &a[i]) } to evict from cache and find access time of all elements at i.
我没有获得clflush后访问数组元素的更高访问时间,尽管我在Scenario-1中得到了预期的结果。
是什么原因?如何过去并在驱逐后了解正确的访问时间。听说硬件和软件预取,它们会影响我的结果吗?如何克服影响并了解正确的结果?
答案 0 :(得分:1)
通过BIOS(或任何其他方法)禁用HW预取程序后尝试重新运行。您描述了一个非常稳定的流,它将立即被HW流预取器识别,并在您的负载之前很好地获取(使访问时间与常规L2查找完全相同)