繁体   English   中英

在C ++中对函数进行性能分析

[英]Profiling a function in c++

我对在用C ++编写并在linux上运行的程序中找到特定功能的内存访问次数感兴趣。 为了找到内存访问次数,我使用了Valgrind的cachegrind。 我使用以下命令来获取内存访问:

cg_annotate --show=Dr,Dw cachegrind.out.25329  |tee log.txt

我的那个函数的内存访问次数如下所示:

  379,010,475   697,368,671  ???:CheckInput(std::string)

现在基本上,我具有三个功能,并且我想根据内存访问次数对这三个功能进行比较。 现在我要说清楚,这是进行比较的正确方法吗? 我是否需要取平均内存访问次数,或者每个功能仅读取一次总内存访问就足够了? 其次,我是否可以得出结论,将具有较少的内存访问次数(内存读取+内存写入)作为一种快速功能?

查看cachegrind并不是孤立确定功能性能的好方法。 这样的测试不能很好地表明功能在分支预测和高速缓存命中率之类的东西上如何实际使用。

Cachegrind通常可以告诉您为什么给定的实现在实践中很慢,但是您需要在整个二进制/数据的代表性执行中运行它。

还有两点需要注意:

原始dr / dw并不是性能的良好代表,因为它们不会告诉您有关缓存命中率的任何信息。 在所有其他条件相同的情况下,从L1高速缓存中读取1000个值的函数将比从内存中读取单个值(导致页面错误)并且必须从虚拟内存中加载页面的函数更快。

您不会看到有关分支预测失败的任何信息。 在所有其他条件相同的情况下,在分支预测上执行不佳的功能将比在分支预测上执行良好的等效功能慢得多。

编辑----------------------------------------------

由于您没有提供任何详细信息,所以我不知道您在做什么。 但是,假设您编写了以下测试:

for (int i = 0; i < 100000; ++i) {
   func1("test string");
}
for (int i = 0; i < 100000; ++i) {
   func2("test string");
}

这并不代表实际程序将如何使用此功能(因此,我说过有关使用代表数据的内容)。 因此,该测试是毫无价值的。 这是一个“微基准”。 第一次通过函数时,所有内容都适合缓存,并且分支预测应该比实际使用情况好得多,因为您始终使用相同的输入。

要编写适当的性能测试,请问自己“我将如何在我的应用程序中使用此功能”,并编写测试来模拟该功能。 更好的是,在应用程序中实际配置功能。 没有申请吗? 然后您就太早地优化方法了(除非您的兴趣纯粹是学术性的)。

由于我在原始答案中指出的原因,内存访问的原始计数不会告诉您函数的性能。 部分原因是并非所有内存访问均被平等创建。 根据要从何处读取内存,访问时间之间存在数量级的差异( 访问各种缓存和主内存的大概成本? )。 除此之外,还有更多的事情不只是内存访问。 您可以编写一个函数,完全对寄存器中存储的内容执行数十亿次操作。

您似乎非常关注内存访问...您是否尝试过全面阅读概要分析?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM