L2 取指未命中率远高于 L1 取指未命中率

2023-12-28

我正在生成一个综合 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程序它由许多随机命名的虚拟函数组成,这些函数依次以随机顺序调用main()。我正在 CentOS 7 下使用 gcc 4.8.5 编译生成的代码-O0。该代码在配备 2 个 Intel Xeon E5-2630v3(Haswell 架构)的双插槽计算机上运行。

我感兴趣的是了解 perf 在分析时报告的与指令相关的计数器从 C 代码编译的二进制文件(不是Python脚本,仅用于自动生成代码)。特别是,我正在观察以下计数器perf stat:

  • 指示
  • L1-icache-加载未命中(指令获取错过了 L1,又名 Haswell 上的 r0280)
  • r2424, L2_RQSTS.CODE_RD_MISS(缺少 L2 的指令获取)
  • rf824, L2_RQSTS.ALL_PF(所有 L2 硬件预取器请求,包括代码和数据)

我首先分析了 BIOS 中禁用所有硬件预取器的代码,即

  • MLC 流媒体已禁用
  • 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 流媒体启用
  • 启用 MLC 空间预取器
  • 启用 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

Now, L2_RQSTS.ALL_PF似乎表明正在发生更多事情,尽管我预计预取器会更加激进,但我认为由于跳跃密集型工作负载和数据预取器没有太多作用,指令预取器受到了严格的考验面对这样的工作量。但话又说回来,L2_RQSTS.CODE_RD_MISS启用预取器后仍然太高。

所以,总而言之,我的问题是:

禁用硬件预取器后,L2_RQSTS.CODE_RD_MISS似乎比L1-icache-加载未命中。即使启用了硬件预取器,我仍然无法解释它。如此高的计数背后的原因是什么?L2_RQSTS.CODE_RD_MISS相比L1-icache-加载未命中?


指令预取器可以生成的请求不计为对 L1I 高速缓存的访问,但计为较高编号内存级别(例如 L2)的代码提取请求。这对于所有具有指令预取器的英特尔微架构来说通常都是如此。L2_RQSTS.CODE_RD_MISS计算来自 L1I 的请求和预取请求。需求请求由 IFU 中的复用单元生成,该复用单元从流水线中可能改变流的不同单元(例如分支预测单元)中选择目标获取线性地址。如果可能的话,预取请求由 L1I 指令预取器在 L1I 未命中时生成。

一般来说,预取请求的数量几乎与 L1I 未命中的数量成正比。对于从可缓存内存类型的内存区域获取指令,以下公式成立:

ICACHE.MISSES <= L2_RQSTS.CODE_RD_MISS + L2_RQSTS.CODE_RD_HIT

我不确定这个公式是否也适用于不可缓存的获取请求。我没有在那种情况下测试过。我知道这些请求被算作ICACHE.MISSES,但不确定其他事件。

在您的情况下,大多数指令读取都会在 L1I 和 L2 中丢失。您有 10,000 个函数,每个函数几乎完全跨越 2 个 64 位缓存行(here https://gcc.godbolt.org/z/4Tsq5h是只有两个函数的版本),因此代码大小比 Haswell 上可用的 256 KiB L2 大得多。这些函数以非连续且不可预测的顺序调用,因此 L1I 和 L2 预取器不会有太大帮助。唯一值得注意的例外是回报,所有这些都将使用 RSB 机制正确预测。

这 10,000 个函数中的每一个都在循环中被调用 100,000 次。大多数获取请求都是针对这些函数占用的行。有用的指令获取请求总数约为每个函数 2 行 * 10,000 个函数 * 100,000 次迭代 = 2,000,000,000 行,其中大部分将在 L1I 和 L2 中丢失(但可能在第一次冷迭代后在 L3 中命中)。数百万个其他请求将针对循环体占用的行。您的测量结果显示,L1I 中丢失的指令获取量大约多了 30%。这是因为分支预测错误,导致对错误行的提取请求,这些错误行甚至可能不在 L1I 和/或 L2 中。每次 L1I 未命中都可能触发预取,因此 L2 指令读取在 L1I 未命中次数的两倍以内是正常的。这与你的数字是一致的。

在我的两个功能中version https://gcc.godbolt.org/z/4Tsq5h,我计算出每个调用函数有 24 条指令,因此我预计退休指令的总数约为 240 亿条,但您得到的是 250 亿条。要么我不知道如何计数,要么由于某种原因每个函数有 25 条指令。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

L2 取指未命中率远高于 L1 取指未命中率 的相关文章

  • 我应该如何优化这个文件系统 I/O 绑定程序?

    我有一个 python 程序 它执行如下操作 从 csv 文件中读取一行 对其进行一些变换 将其分解为实际的行 因为它们将被写入数据库 将这些行写入单独的 csv 文件 除非文件已完全读取 否则返回步骤 1 运行 SQL Loader 并将
  • 使用 html 属性的 DOM 惩罚

    我正在考虑使用 HTML5 数据属性来更轻松地编写我的应用程序的第三方脚本 因此 考虑两种情况 页面上有 10 000 个 HTML 元素 例如 div Sticker div 还有其他 10 000 个 HTML 元素 例如 div St
  • 什么是样板代码、热点代码和热点?

    我知道这些术语是在性能实现 优化的背景下使用的 最近一直在研究这个问题 并尝试过搜索 但没有得到任何例子 清楚地阐述 描述这些概念以及在现实世界开发场景中实现这些问题 概念 有人可以彻底解释这些术语 示例场景以及可能使用这些概念和术语的地方
  • PHP include():文件大小和性能

    一个没有经验的PHP问题 我有一个 PHP 脚本文件 我需要在不同页面的很多地方多次包含该文件 我可以选择将包含的文件分解为几个较小的文件 并根据需要包含这些文件 或者 我可以将它们全部保存在一个 PHP 文件中 我想知道在这种情况下使用较
  • 在二维平面中找到距离 P 点最近的 K 个点

    资料来源 亚马逊面试问题 解决方案1制作大小为 K 的堆并按最小距离收集点O NLogK 复杂 解决方案2 取大小为 N 的数组并按距离排序 应该使用QuickSort 霍尔修改 取前 K 点作为答案 这太复杂了 NlogN 但可以优化到近
  • jQuery UI .buttonset() 太慢

    我的 HTML 页面上有几千个按钮 运行需要10多秒 buttonset buttonset 文件准备好 有没有更快的方法来做到这一点 或者是我以某种方式限制按钮数量的唯一解决方案 创建buttonset在第一次显示之前按需进行 我刚刚测试
  • 高性能 C# 服务器套接字的提示/技术

    我有一个 NET 2 0 服务器似乎遇到了扩展问题 可能是由于套接字处理代码的设计不佳 我正在寻找有关如何重新设计它以提高性能的指导 使用场景 50 150 个客户端 每个客户端以高速率 高达 100 秒 秒 发送小消息 每条 10 字节
  • Verilog 双向握手示例

    我正在完成一个项目 要求是处理器内部功能单元之间的双向握手 我知道它是什么 但是有没有任何 标准 或一个简单的例子 我唯一能想到的就是两个单元之间 当它们之间有一条数据线并且当 X 发送到 Y 时 会给出一个单独的 发送 信号 当 Y 接收
  • 在未排序的整数列表中最优搜索 k 个最小值

    我刚刚接受采访时提出了一个问题 我很好奇答案应该是什么 问题本质上是 假设您有一个包含 n 个整数的未排序列表 您如何找到此列表中的 k 个最小值 也就是说 如果您有一个 10 11 24 12 13 列表并且正在寻找 2 个最小值 您将得
  • 为什么比较匹配的字符串比比较不匹配的字符串更快? [复制]

    这个问题在这里已经有答案了 这里有两个测量值 timeit timeit toto 1234 number 100000000 1 8320042459999968 timeit timeit toto toto number 100000
  • 在 Matlab 中快速加载大块二进制文件

    我有一些相当大的 int16 格式的数据文件 256 个通道 大约 75 1 亿个样本 每个文件约 40 50 GB 左右 它以平面二进制格式编写 因此结构类似于 CH1S1 CH2S1 CH3S1 CH256S1 CH1S2 CH2S2
  • Android 在 ROOM 数据库中插入大量数据

    我有大约 10 个模型 每个模型都有超过 120K 行和 90 列的记录 其中包含双数组值 在 Room 中插入任何模型都需要超过 125 130 秒 任何人都可以建议我需要做什么才能使用一些批量插入技术来保存所有这些 120K 该技术大约
  • 为什么在强度降低乘法和循环进位加法之后,这段代码的执行速度会变慢?

    我正在读书阿格纳 雾 https en wikipedia org wiki Agner Fog s 优化手册 https en wikipedia org wiki Agner Fog Optimization 我遇到了这个例子 doub
  • LINQ 函数的顺序重要吗?

    基本上 正如问题所述 LINQ 函数的顺序是否重要 表现 显然 结果仍然必须相同 Example myCollection OrderBy item gt item CreatedDate Where item gt item Code g
  • perf 找不到外部模块符号

    跑步时perf它找到了我的程序的内核符号和符号 但没有找到外部模块符号 我已经编写了一个内核模块 我使用它加载insmod我怎么知道perf也找到它的符号 我正在运行 2 6 37 6 内核 无法升级 我的perf尚不支持矮人选项 但我认为
  • VB.NET 是否优化字符串文字的串联?

    如同this https stackoverflow com questions 288794 does c optimize the concatenation of string literals问题 但对于 VB NET 来说 因为我
  • 使用 NEON 优化 Cortex-A8 颜色转换

    我目前正在执行颜色转换例程 以便从 YUY2 转换为 NV12 我有一个相当快的函数 但没有我预期的那么快 主要是由于缓存未命中 void convert hd uint8 t orig uint8 t result uint32 t wi
  • 超慢的表格布局性能

    我遇到了糟糕的 TableLayout 性能 我在这里读过一些帖子 谈论同样的事情 Android 动态创建表 性能不佳 https stackoverflow com questions 9813427 android dynamical
  • 如何读取 GPU 负载?

    我正在编写一个程序 用于监控计算机的各种资源 例如CPU使用率等 我还想监控 GPU 使用情况 GPU 负载 而不是温度 using System using System Collections Generic using System
  • 如何在 C++ 中对静态缓冲区执行字符串格式化?

    我正在处理一段对性能要求非常高的代码 我需要执行一些格式化的字符串操作 但我试图避免内存分配 甚至是内部库的内存分配 在过去 我会做类似以下的事情 假设是 C 11 constexpr int BUFFER SIZE 200 char bu

随机推荐

  • 类型错误:预期的字符串或类似字节的对象(Python 3)(Wordcloud)

    import pandas as pd import matplotlib pyplot as plt from PIL import Image import numpy as np import wordcloud from wordc
  • 如何在网页中调用嵌入的java函数

    这是我想在网页中使用的函数 并想在脚本节点中像其他 JavaScript 函数一样调用它 但你能指导我如何实现它吗 public static String getClipboard Transferable t Toolkit getDe
  • 当类声明出现编译错误“看起来像函数定义”时,这意味着什么?

    我最近遇到了这个问题 我发现很多人问这个问题 在这里 例如 http www codeguru com forum showthread php p 982326 但没有具体答案 这是从该链接提取的示例代码 class AFX BASE A
  • 如何查找“不是过程”错误

    define comp f g lambda x f g x define complement f cond equal comp f lambda g g t f equal comp f lambda g g f t compleme
  • 是否存在经过认证(ISO 26262 或类似)的 C++ 标准库? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 虽然存在经过认证的 C 工具链 编译器等 但我没有找到任何经过认证的 C 标准库 STL 有谁知道有人
  • 猫鼬不同并填充文档

    我有以下模型 var followerSchema new Schema id follower type Schema Types ObjectId ref Users id post type Schema Types ObjectId
  • REST API 单个请求 - 多个响应

    我正在 JAX RS 2 0 JDK 8 中编写 REST API 以满足以下要求 POST API 服务器 文件上传 多部分表单数据 我需要在其中发送一个大 AI Adobe Illustrator 文件 服务器获取文件并返回状态 202
  • 如何在 html 中设置适用于 Internet Explorer 的背景图像? [复制]

    这个问题在这里已经有答案了 以下CSS代码在Internet Explorer中不起作用 请建议我在Internet Explorer中设置背景的解决方案 body background url images Login BG png no
  • ucfirst 不适用于非英语字符[重复]

    这个问题在这里已经有答案了 我正在尝试将字符串中的第一个字母设为大写 它适用于英文字母 但不幸的是 它不适用于非英文字符 例如 echo ucfirst a la 使 ucfirst 对所有单词 包括非英语字符 正常工作的正确方法是什么 对
  • 使用 LLVM 按参数传递结构

    是否可以通过参数传递结构 它与 C abi 兼容吗 edit 基本上 我希望有一个包含两个成员的 C POD 该结构将是一个胖指针 带有一个指针和一个整数 并且能够在调用指令中将此结构作为函数参数传递 即使在调用 C代码 我现在没有使用胖指
  • 是否可以将钱从 PayPal 帐户转入银行帐户或信用卡?

    我正在使用未来的贝宝付款方式进行付款 我想使用 PayPal 访问令牌将钱从 PayPal 帐户转移到银行或信用卡 但我找不到任何正确的方法来做到这一点 有什么方法可以吗 没有可用于以编程方式自动执行此操作的 API 但您可以从 PayPa
  • 使用雪花连接器获取数据会引发 EmptyPyArrowIterator 错误

    我在 python 脚本 plotly dash 应用程序 中使用 python Snowflake 连接器 今天 在我不更改代码的情况下 该应用程序停止工作 我尝试了一些方法来找出可能出现的问题 我什至尝试运行示例代码雪花文档 https
  • 未捕获的 ReferenceError:进程未定义/第 0 行:解析错误

    For a simple Create React App https create react app dev project I run npm install Then npm start opens the default web
  • MongoDB - 使用嵌套字典查找条目

    我有一个与 python 一起使用的 MongoDB 我的条目如下所示 a something b something c d something e something f something 我想查询具有特定 d 和 e 值的条目 但我
  • 无锁竞技场分配器实现 - 正确吗?

    对于一个简单的指针增量分配器 它们有正式名称吗 我正在寻找一种无锁算法 这看起来微不足道 但我想得到一些反馈 看看我的实现是否正确 非线程安全实现 byte head current head of remaining buffer byt
  • Java全对算法

    给定一个整数集合 有什么 Java 算法可以给出所有的项对 如下所示 给定示例集合 1 3 5 我们想要输出 1 1 3 3 5 5 1 3 1 5 3 5 请注意 顺序并不重要 因此我们需要 1 3 3 1 之一 但不能同时两者 这应该适
  • 检测 Windows Phone 7 是否连接到桌面 Zune 软件

    我已经在 Windows Phone 7 应用程序上工作了几个月 并且拥有一组有用的检测标志 这些标志用于测试代码是否在模拟器中 后台 前台线程上或在设计时间 看完整列表在这里 http silverlightzxing codeplex
  • (html) phpmyadmin 中文本字段的所见即所得编辑器

    我正在制作一个小型网站 我需要谁接手来添加一些内容 存储在三个表中 到 2013 年 9 月最多将有 500 条记录 小东西 现在我正在使用 phpmyadmin 但添加文本 其中一个表格是一个迷你博客 需要基本的 html 技能 我确信
  • Python文件缓存

    我正在从文件创建一些对象 来自模板 xsd 文件的验证器 以将其他 xsd 文件组合在一起 并且我想在磁盘上的文件发生更改时重新创建对象 我可以创建类似的东西 def getobj fname cache try obj lastloade
  • L2 取指未命中率远高于 L1 取指未命中率

    我正在生成一个综合 C 基准测试 旨在通过以下 Python 脚本导致大量指令获取丢失 usr bin env python import tempfile import random import sys if name main fun