为啥 __nss_database_lookup 在我的数字 C++ 程序中占用大部分时间

Posted

技术标签:

【中文标题】为啥 __nss_database_lookup 在我的数字 C++ 程序中占用大部分时间【英文标题】:Why does __nss_database_lookup take most of the time in my numerical C++ program为什么 __nss_database_lookup 在我的数字 C++ 程序中占用大部分时间 【发布时间】:2021-03-23 11:47:26 【问题描述】:

google-pprof 的行分析输出声称我的数字 C++ 程序的大部分运行时间都花在了一个名为 __nss_database_lookup 的函数中(见下文)。显然,该函数用于处理 UNIX 系统上的 passwd 文件之类的东西。我的 C++ 程序应该只进行数值计算、分配内存和传递一些自定义 C++ 数据类型。

发生了什么事?该功能的出现是海市蜃楼,仅仅是google-pprof 工作原理的人工制品吗?还是它实际上被调用并浪费了我程序运行时间的三分之二?如果它被调用,可能是什么调用它?在我的一个 C++ 类中是否有错误地调用它?我将如何追踪它?

我使用的是 Ubuntu 20.04、g++-7g++-9

Total: 1046 samples
     665  63.6%  63.6%      665  63.6% __nss_database_lookup ??:0
     107  10.2%  73.8%      193  18.5% <function1> file.h:1035
      92   8.8%  82.6%       92   8.8% <function2> file.h:...
      87   8.3%  90.9%       87   8.3% <function3> file.h:995
      17   1.6%  92.5%      734  70.2% <function4> file.h:1128
...

(出于保密原因,功能和文件名被隐藏)

【问题讨论】:

这种报告没有说明哪部分代码调用__nss_database_lookup。要获得全貌,您可以使用 perf 构建 CPU Flame Graphs。 当您在玩 pprof 时,只需 do this 并了解真正发生了什么。 【参考方案1】:

我的一个朋友今天遇到了类似的问题。虽然你提出这个问题已经有一段时间了,但我还是想回答一下,以便任何到达这里的人都可以得到一些提示。

这是因为调用了一些局部符号(对应于C/C++中的静态局部函数),而这些符号在符号表中没有它们的条目,它们的文本(代码)放在__nss_database_lookup之后.因此,您的 perf 工具会将它们视为 __nss_database_lookup 的一部分。

比如你的程序可能调用了memcpy,而memcpy调用了__memmove_unaligned_avx_erms,这是glibc中的本地符号,不会导出到动态符号表中,其代码正好放在__nss_database_lookup之后与其他本地符号一起。而你的性能工具找不到任何关于__memmove_unaligned_avx_erms的信息,所以它只是认为__nss_database_lookup被调用了。

一个潜在的解决方案是安装 libc-dbg 软件包(软件包名称可能因各种发行版而异),如果您的 perf 工具足够聪明,可以自动加载调试信息,它可能会正确注释符号。 (我朋友查了一下,对perf工具有一些影响)

【讨论】:

以上是关于为啥 __nss_database_lookup 在我的数字 C++ 程序中占用大部分时间的主要内容,如果未能解决你的问题,请参考以下文章

为啥__class__可以直接访问[重复]

为啥clang忽略__restrict__?

为啥我得到“[__NSArrayI allKeys]:无法识别的选择器发送到实例”/为啥 NSDictionary 正在转换?

为啥我得到“[__NSArrayI allKeys]:无法识别的选择器发送到实例”/为啥 NSDictionary 正在转换?

何时(以及为啥)引入 Python `__new__()`?

为啥 Python 没有“__req__”(反射相等)方法?