Linux C++:如何分析由于缓存未命中而浪费的时间?

2024-11-07 08:55:00
admin
原创
30
摘要:问题描述:我知道我可以使用 gprof 来对我的代码进行基准测试。但是,我遇到了这个问题——我有一个具有额外间接级别的智能指针(可以将其视为代理对象)。结果,我有了这个额外的层,它影响了几乎所有的功能,并且影响了缓存。有没有办法测量我的 CPU 因缓存未命中而浪费的时间?解决方案 1:Linux 从 2.6....

问题描述:

我知道我可以使用 gprof 来对我的代码进行基准测试。

但是,我遇到了这个问题——我有一个具有额外间接级别的智能指针(可以将其视为代理对象)。

结果,我有了这个额外的层,它影响了几乎所有的功能,并且影响了缓存。

有没有办法测量我的 CPU 因缓存未命中而浪费的时间?


解决方案 1:

Linux 从 2.6.31 开始支持perf。这允许您执行以下操作:

  • 使用 -g 编译代码以包含调试信息

  • 运行你的代码,例如使用最后一级缓存未命中计数器:perf record -e LLC-loads,LLC-load-misses yourExecutable

  • 跑步perf report

    • 确认初始消息后,选择该LLC-load-misses行,

    • 然后例如第一个函数和

    • 然后annotate。您应该看到这些行(以汇编代码表示,被原始源代码包围)和一个数字,该数字表示发生缓存未命中的行中最后一级缓存未命中的比例。

解决方案 2:

您可以尝试cachegrind及其前端 kcachegrind。

解决方案 3:

您可以找到一个访问 CPU 性能计数器的工具。每个核心中可能都有一个寄存器,用于计算 L1、L2 等未命中次数。或者,Cachegrind 会执行逐周期模拟。

但是,我认为这没什么用。您的代理对象可能被它们自己的方法修改了。传统的分析器会告诉您这些方法花费了多少时间。没有分析工具会告诉您如果没有缓存污染源,性能会如何提高。这是减少程序工作集的大小和结构的问题,这很难推断。

快速 Google 搜索结果boost::intrusive_ptr可能会让您感兴趣。它似乎不支持类似的东西weak_ptr,但转换您的程序可能很简单,然后您就会确切知道非侵入式引用计数的成本。

解决方案 4:

继续@Mike_Dunlavey 的回答:

首先,使用您最喜欢的工具获取基于时间的配置文件:VTune 或 PTU 或 OProf。

然后,获取缓存未命中概况。L1 缓存未命中,或 L2 缓存未命中,或...

即第一个配置文件将“花费的时间”与每个程序计数器关联起来。第二个配置文件将“缓存未命中次数”值与每个程序计数器关联起来。

注意:我经常“减少”数据,按函数或(如果我有技术的话)按循环进行汇总。或者按 64 字节的箱进行汇总。比较单个程序计数器通常没有用,因为性能计数器很模糊 - 您看到报告缓存未命中的位置通常与实际发生的位置有几条指令不同。

好的,现在绘制这两个配置文件的图表来比较它们。以下是一些我认为有用的图表:

“冰山”图:X 轴表示 PC,正 Y 轴表示时间,负 Y 轴表示缓存未命中。 寻找同时上升和下降的位置。

(“交错”图表也很有用:同样的想法,X 轴是 PC,在 Y 轴上绘制时间和缓存未命中,但使用不同颜色的窄垂直线,通常是红色和蓝色。花费大量时间和缓存未命中的地方将有精细交错的红线和蓝线,几乎看起来是紫色。这延伸到 L2 和 L3 缓存未命中,都在同一个图表上。顺便说一句,您可能希望“规范化”数字,要么是总时间或缓存未命中的百分比,或者更好的是,最大数据点时间或缓存未命中的百分比。如果您弄错了比例,您将什么也看不到。)

XY 图表:对于每个采样箱(PC、函数、循环等),绘制一个点,其X 坐标为归一化时间,Y 坐标为归一化缓存未命中数。如果您在右上角获得大量数据点 - 大百分比时间和大百分比缓存未命中数 - 那就是有趣的证据。或者,忘记点数 - 如果上角所有百分比的总和很大...

请注意,不幸的是,您经常必须自己进行这些分析。我上次检查时发现 VTune 不会为您执行此操作。我曾使用过 gnuplot 和 Excel。(警告:Excel 在超过 64,000 个数据点时会失效。)


更多建议:

如果您的智能指针是内联的,您可能会得到到处都是的计数。在理想情况下,您将能够将 PC 追溯到源代码的原始行。在这种情况下,您可能希望稍微推迟减少:查看所有单个 PC;将它们映射回源代码行;然后将它们映射到原始函数中。许多编译器(例如 GCC)都有允许您执行此操作的符号表选项。

顺便说一句,我怀疑你的问题不是智能指针导致的缓存抖动。除非你到处都在做 smart_ptr<int>。如果你正在做 smart_ptr<Obj>,并且 sizeof(Obj) + 大于 4sizeof(Obj)(并且如果 smart_ptr 本身不是很大),那么它就没那么多。

更可能的是,智能指针的额外间接级别导致了您的问题。

巧合的是,我在午餐时和一个家伙聊天,他有一个引用计数智能指针,它使用句柄,即间接级别,类似于

template<typename T> class refcntptr {
    refcnt_handle<T> handle;
public:
    refcntptr(T*obj) {
        this->handle = new refcnt_handle<T>();
        this->handle->ptr = obj;
        this->handle->count = 1;
    }
};
template<typename T> class refcnt_handle {
    T* ptr;
    int count;
    friend refcnt_ptr<T>;
};

(我不会这样编码,但它有助于说明。)

双重间接this->handle->ptr可能会带来很大的性能问题。或者甚至是三重间接,this->handle->ptr->field。至少,在具有 5 个周期 L1 缓存命中的机器上,每个 this->handle->ptr->field 都需要 10 个周期。而且重叠起来比单个指针追逐要困难得多。但更糟糕的是,如果每个都是 L1 缓存未命中,即使到 L2 只有 20 个周期……那么,隐藏 2*20=40 个周期的缓存未命中延迟要比隐藏单个 L1 未命中困难得多。

一般来说,避免智能指针中的间接层级是个好建议。不要指向所有智能指针都指向的句柄,而句柄本身又指向对象,而是让智能指针既指向对象又指向句柄,从而使智能指针变得更大。(这样就不再是通常所说的句柄,而更像是一个信息对象。)

例如

template<typename T> class refcntptr {
    refcnt_info<T> info;
    T* ptr;
public:
    refcntptr(T*obj) {
        this->ptr = obj;
        this->info = new refcnt_handle<T>();
        this->info->count = 1;
    }
};
template<typename T> class refcnt_info {
    T* ptr; // perhaps not necessary, but useful.
    int count;
    friend refcnt_ptr<T>;
};

无论如何,时间概况是你最好的朋友。


哦,是的 - Intel EMON 硬件还可以告诉您在 PC 上等待了多少个周期。这可以区分大量的 L1 未命中和少量的 L2 未命中。

解决方案 5:

这取决于您使用的操作系统和 CPU。例如,对于 Mac OS X 和 x86 或 ppc,Shark将进行缓存未命中分析。Linux 上的Zoom也是如此。

解决方案 6:

如果您运行的是 AMD 处理器,您可以获得CodeAnalyst,显然就像啤酒一样免费。

解决方案 7:

我的建议是使用英特尔的PTU(性能调整实用程序)。

此实用程序是 VTune 的直接后代,提供最佳的采样分析器。您将能够跟踪 CPU 在哪里花费或浪费时间(借助可用的硬件事件),并且不会减慢您的应用程序或干扰分析。当然,您将能够收集您正在寻找的所有缓存行未命中事件。

解决方案 8:

另一个基于 CPU 性能计数器的分析工具是oprofile。您可以使用 kcachegrind 查看其结果。

解决方案 9:

这是一种一般性的答案。

例如,如果您的程序将 50% 的时间花在了缓存未命中上,那么当您暂停程序时,程序计数器的 50% 的时间将位于等待导致缓存未命中的内存提取的确切位置。

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   601  
  华为IPD与传统研发模式的8大差异在快速变化的商业环境中,产品研发模式的选择直接决定了企业的市场响应速度和竞争力。华为作为全球领先的通信技术解决方案供应商,其成功在很大程度上得益于对产品研发模式的持续创新。华为引入并深度定制的集成产品开发(IPD)体系,相较于传统的研发模式,展现出了显著的差异和优势。本文将详细探讨华为...
IPD流程是谁发明的   7  
  如何通过IPD流程缩短产品上市时间?在快速变化的市场环境中,产品上市时间成为企业竞争力的关键因素之一。集成产品开发(IPD, Integrated Product Development)作为一种先进的产品研发管理方法,通过其结构化的流程设计和跨部门协作机制,显著缩短了产品上市时间,提高了市场响应速度。本文将深入探讨如...
华为IPD流程   9  
  在项目管理领域,IPD(Integrated Product Development,集成产品开发)流程图是连接创意、设计与市场成功的桥梁。它不仅是一个视觉工具,更是一种战略思维方式的体现,帮助团队高效协同,确保产品按时、按质、按量推向市场。尽管IPD流程图可能初看之下显得错综复杂,但只需掌握几个关键点,你便能轻松驾驭...
IPD开发流程管理   8  
  在项目管理领域,集成产品开发(IPD)流程被视为提升产品上市速度、增强团队协作与创新能力的重要工具。然而,尽管IPD流程拥有诸多优势,其实施过程中仍可能遭遇多种挑战,导致项目失败。本文旨在深入探讨八个常见的IPD流程失败原因,并提出相应的解决方法,以帮助项目管理者规避风险,确保项目成功。缺乏明确的项目目标与战略对齐IP...
IPD流程图   8  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用