gpt4 book ai didi

c++ - 在 C++ 中分析一个函数

转载 作者:搜寻专家 更新时间:2023-10-31 01:45:15 27 4
gpt4 key购买 nike

我有兴趣在我用 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");
}

这并不代表实际程序将如何使用此功能(因此我所说的是使用代表性数据)。因此,该测试毫无值(value)。这是一个“微基准”。第一次通过函数时,一切都适合缓存,分支预测应该比现实世界的使用要好得多,因为您总是使用相同的输入。

要编写适当的性能测试,请问自己“我将如何在我的应用程序中使用此功能”,然后编写测试来模仿它。更好的是,实际分析您应用程序中的功能。没有申请?那你优化得太快了(除非你的兴趣纯粹是学术性的)。

出于我在原始答案中指出的原因,内存访问的原始计数不会告诉您函数的性能。部分原因是并非所有内存访问都是平等创建的。根据读取内存的位置,访问时间存在数量级差异(Approximate cost to access various caches and main memory?)。除此之外,还有更多的事情发生,而不仅仅是内存访问。您可以编写一个函数,完全对寄存器中存储的内容执行数十亿次操作。

您似乎非常关注内存访问...您是否尝试过阅读一般的分析?

关于c++ - 在 C++ 中分析一个函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22413292/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com