java 中_l1,L2指令获取错过远高于L1指令获取未命中

我正在生成一个合成C基准测试,旨在通过以下Python脚本导致大量的指令获取错过:

#!/usr/bin/env python

import tempfile

import random

import sys

if __name__ == '__main__':

functions = list()

for i in range(10000):

func_name = "f_{}".format(next(tempfile._get_candidate_names()))

sys.stdout.write("void {}() {{\n".format(func_name))

sys.stdout.write(" double pi = 3.14, r = 50, h = 100, e = 2.7, res;\n")

sys.stdout.write(" res = pi*r*r*h;\n")

sys.stdout.write(" res = res/(e*e);\n")

sys.stdout.write("}\n")

functions.append(func_name)

sys.stdout.write("int main() {\n")

sys.stdout.write("unsigned int i;\n")

sys.stdout.write("for(i =0 ; i < 100000 ;i ++ ){\n")

for i in range(10000):

r = random.randint(0, len(functions)-1)

sys.stdout.write("{}();\n".format(functions[r]))

sys.stdout.write("}\n")

sys.stdout.write("}\n")

代码所做的只是生成 C program ,它由许多随机命名的虚函数组成,这些函数又在 main() 中以随机顺序调用 . 我正在使用 -O0 在CentOS 7下使用gcc 4.8.5编译生成的代码 . 该代码在配备2x Intel Xeon E5-2630v3(Haswell架构)的双插槽机器上运行 .

我感兴趣的是在分析 binary compiled from the C code (不是Python脚本,仅用于自动生成代码)时理解perf报告的与指令相关的计数器 . 特别是,我正在使用 perf stat 观察以下计数器:

instructions

L1-icache-load-misses (指令提取错过L1,又名Haswell上的r0280)

r2424 , L2_RQSTS.CODE_RD_MISS (指令提取错过L2)

rf824 , L2_RQSTS.ALL_PF (所有L2硬件预取程序请求,包括代码和数据)

我首先在BIOS中禁用了所有硬件预取程序的代码,即

MLC Streamer禁用

MLC空间预取器已禁用

DCU数据预取器已禁用

DCU指令预取器已禁用

结果如下(进程被固定到第二个CPU的第一个核心和相应的NUMA域,但我想这没有太大的区别):

perf stat -e instructions,L1-icache-load-misses,r2424,rf824 numactl --physcpubind=8 --membind=1 /tmp/code

Performance counter stats for 'numactl --physcpubind=8 --membind=1 /tmp/code':

25,108,610,204 instructions

2,613,075,664 L1-icache-load-misses

5,065,167,059 r2424

17 rf824

33.696954142 seconds time elapsed

考虑到上面的数字,我无法解释L2中如此大量的指令获取失误 . 我已禁用所有预取程序, L2_RQSTS.ALL_PF 确认如此 . 但为什么我看到L2中的指令获取次数比L1i多两倍?在我的(简单)心理处理器模型中,如果在L2中查找指令,则必须先在L1i中查找 . 显然我错了,我错过了什么?

然后,我尝试在启用所有硬件预取程序的情况下运行相同的代码,即

MLC Streamer已启用

MLC Spatial Prefetcher已启用

DCU数据预取器已启用

DCU指令预取器已启用

结果如下:

perf stat -e instructions,L1-icache-load-misses,r2424,rf824 numactl --physcpubind=8 --membind=1 /tmp/code

Performance counter stats for 'numactl --physcpubind=8 --membind=1 /tmp/code':

25,109,877,626 instructions

2,599,883,072 L1-icache-load-misses

5,054,883,231 r2424

908,494 rf824

现在, L2_RQSTS.ALL_PF 似乎表明发生了更多的事情,虽然我预计预取器会更具攻击性,但我认为由于跳跃密集型工作负载和数据预取器没有,预编译器严重受到测试与这种工作量有很大关系 . 但同样, L2_RQSTS.CODE_RD_MISS 仍然太高,启用了预取器 .

所以,总结一下,我的问题是:

禁用硬件预取程序后, L2_RQSTS.CODE_RD_MISS 似乎远高于 L1-icache-load-misses . 即使启用了硬件预取程序,我仍然无法解释它 . 与 L1-icache-load-misses 相比,如此高的 L2_RQSTS.CODE_RD_MISS 背后的原因是什么?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
L1/L2/L3 Cache是存储器子系统的组成部分,用于存放程序经常使用的指令和数据。L1 Cache是CPU流水线和主存储器之间的第一级缓存,L2 Cache是L1 Cache之上的第二级缓存,L3 Cache是L2 Cache之上的第三级缓存。\[1\] 当CPU需要数据时,它首先搜索L1 Cache,如果找到,则接下来搜索L2 Cache和L3 Cache。如果找到所需的数据,则称为缓存命中。如果数据不在缓存,则CPU必须从主内存或存储加载数据到缓存,这会导致延迟并对性能产生不利影响,这称为缓存命中。\[2\] 除了L1/L2/L3 Cache之外,还有其他类型的Cache,如用于虚实地址转换的TLB、MOB、ROB、Register File和BTB等。这些Cache的作用是提高数据传输率和缓解访问延迟。\[1\] 总结来说,L1/L2/L3 Cache是存储器子系统的缓存,用于存放CPU经常使用的指令和数据,以提高数据访问速度和系统性能。\[1\]\[2\] #### 引用[.reference_title] - *1* [什么是L1/L2/L3 Cache?](https://blog.csdn.net/wujianing_110117/article/details/119663604)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [CPU缓存:L1L2 和 L3 缓存之间的区别](https://blog.csdn.net/weixin_42238387/article/details/120576720)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值