以编程方式计算缓存故障

9
我需要评估一个C++函数在不同内存层次效率下的时间(例如:当读取数组一部分时,缓存未命中、缓存命中或页面故障所需的时间),因此我希望有一些库可以让我计算缓存未命中/页面故障,以便能够自动生成性能摘要。
我知道有一些工具,如cachegrind,可以给出应用程序执行的相关统计信息,但我想要一个库,正如我之前所说的。
编辑:哦,我忘了:我正在使用Linux,我对可移植性不感兴趣,这是一个学术问题。
欢迎任何建议!

1
你能否对操作系统进行仪器化,以帮助获取一些信息?在具有虚拟内存的现代抢占式多任务系统中,操作系统可能会在应用程序不知情的情况下对其进行各种奇怪的操作... - Carl Norum
我不知道,我正在使用Linux。至于页面错误,我知道这样的统计数据由于现代操作系统管理内存的方式而变得不那么重要,正如你所说:事实上,我更感兴趣的是L2缓存未命中,我认为这更独立于操作系统管理。 - akappa
4个回答

6
看起来现在有我正在寻找的东西了:perf_event_open
它可以让你做一些有趣的事情,比如初始化/启用/禁用一些性能计数器,随后通过一个统一和直观的API获取它们的值(它会给你一个特殊的文件描述符,其中包含之前请求的信息)。
这是一个仅适用于Linux的解决方案,功能因内核版本而异,所以要小心 :)

5
大多数最新的CPU(包括AMD和Intel)都有性能监视器寄存器,可以用于这种工作。对于Intel,它们在程序员参考手册第3B卷第30章中进行了介绍。对于AMD,则在BIOS和内核开发人员指南中进行了介绍。
无论哪种方式,您都可以计算诸如高速缓存命中、高速缓存未命中、内存请求、数据预取等内容。它们具有相当特定的选择器,因此您可以获得(例如)L2高速缓存读取次数的计数,以填充L1指令高速缓存中的行(同时仍然排除L2读取以填充L1数据高速缓存中的行)。
Linux内核模块可以访问MSR(特定型号寄存器)。我不确定它是否可以访问性能监视器寄存器,但我认为它很可能可以。

你在谈论内核模块时是指perfmon2吗? - akappa
@akappa:据我回忆,它只是被称为“MSR内核模块”或类似的名称。不过,我已经有一段时间没有使用它了,所以我可能记错了名字。 - Jerry Coffin
好的,如果perfmon2使用起来太困难,我会进行一些研究。谢谢 :) - akappa

3

英特尔 VTune 是一款性能调优工具,正好可以满足您的要求;当然,它只适用于英特尔处理器,因为它使用内部处理器计数器,正如 Jerry Coffin 所解释的那样,所以这可能不适用于 AMD 处理器。 它会公开几乎无数的计数器,例如缓存命中/未命中、分支预测率等。真正的问题是要理解需要检查哪些计数器;)


有趣的工具,但我正在阅读文档,却找不到任何提及在运行时获取一些性能统计数据的API。 - akappa
老实说,我总是把它作为独立的程序使用,如果我找到更多细节,我会发布它们 ;) - sergico
这是我找到的内容:链接链接 - sergico
@akappa:请忽略之前的评论:这是我找到的:vtune API for pause/resumeVTune API for reader/writer 不过不确定这是否正是您要寻找的。 - sergico

1

缓存未命中不能轻易地计算。大多数工具或分析器通过将内存访问重定向到提供此功能的函数来模拟内存访问。这意味着这些工具在所有进行内存访问的地方对代码进行了仪器化,并使您的代码运行得非常慢。我想这不是您的意图。

但是,根据硬件的不同,您可能会有其他可能性。但即使是这种情况,操作系统也应该支持它(否则您将获得与进程或线程无关的系统全局统计信息)

编辑:我找到了这篇有趣的文章,可能会对您有所帮助:http://lwn.net/Articles/417979/


我正在考虑一些“神奇”的处理器功能(比如一些很好的寄存器,可以以某种方式计算缓存故障),由一个库进行抽象化,该库可以自动检测处理器类型并进行必要的管道工作以获取实际数据。我不知道是否可能有这样的东西存在 - 例如,这些“神奇值”应该在上下文切换时被复制 - 但如果存在这样的库,那将是非常棒的。 - akappa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接