为啥 __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++-7
和 g++-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++ 程序中占用大部分时间的主要内容,如果未能解决你的问题,请参考以下文章
为啥我得到“[__NSArrayI allKeys]:无法识别的选择器发送到实例”/为啥 NSDictionary 正在转换?
为啥我得到“[__NSArrayI allKeys]:无法识别的选择器发送到实例”/为啥 NSDictionary 正在转换?