- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
具有繁重内核工作(锁定解锁)的多线程程序,尝试使用分析工具在我的代码中找到热点。
我写了一个最小的可重现程序。编译它。使用分析工具,如 perf 、 gprof 和调用堆栈记录。然后都不能在我的代码报告热点,但在内核或 libstdc++.so 报告功能。
#include <iostream>
#include <mutex>
#include <thread>
#include <memory>
#include <vector>
std::mutex mtx;
long long_val = 0;
void do_something(long &val)
{
std::unique_lock<std::mutex> lck(mtx);
for(int j=0; j<1000; ++j)
val++;
}
void thread_func()
{
for(int i=0; i<1000000L; ++i)
{
do_something(long_val);
}
}
int main(int argc, char* argv[])
{
std::vector<std::unique_ptr<std::thread>> threads;
for(int i=0; i<100; ++i)
{
threads.push_back(std::move(std::unique_ptr<std::thread>(new std::thread(thread_func))));
}
for(int i=0; i<100; ++i)
{
threads[i]->join();
}
threads.clear();
std::cout << long_val << std::endl;
return 0;
}
我们可以看到,do_something()
是我程序的热点。因为太多的 unique_lock 花费了大量的内核工作,并且 1000 次 inc 在函数上运行。
我希望分析工具告诉我,它是 do_something() 造成大量锁定,导致大量内核工作。但是从 perf
中,我只能发现它是 lock 减慢了我的代码,但是这些锁是在哪里对我的代码进行操作的?不清楚。
编译:
g++ -o a.out -O3 -std=c++11 -fno-omit-frame-pointer -pthread -pg main.cpp
运行程序./a.out
,htop报告内核占用了一半的CPU资源。
性能记录:
perf record -g ./a.out
性能报告:
Children Self Command Shared Object Symbol
- 98.64% 0.00% a.out libstdc++.so.6.0.21 [.] 0x00000000000b8c80
- 0xb8c80
+ 41.80% __lll_unlock_wake
+ 35.39% __lll_lock_wait
12.77% pthread_mutex_lock
7.69% pthread_mutex_unlock
0.70% _Z11thread_funcv
- 49.21% 0.88% a.out [kernel.kallsyms] [k] entry_SYSCALL_64_after_hwframe
+ 48.33% entry_SYSCALL_64_after_hwframe
0.88% 0xb8c80
- 47.64% 1.06% a.out [kernel.kallsyms] [k] do_syscall_64
+ 46.59% do_syscall_64
+ 1.06% 0xb8c80
- 47.18% 1.44% a.out [kernel.kallsyms] [k] sys_futex
+ 45.74% sys_futex
+ 1.44% 0xb8c80
- 45.55% 1.65% a.out [kernel.kallsyms] [k] do_futex
+ 43.90% do_futex
+ 1.65% 0xb8c80
- 41.80% 1.30% a.out libpthread-2.23.so [.] __lll_unlock_wake
+ 40.50% __lll_unlock_wake
+ 1.30% 0xb8c80
- 35.39% 4.53% a.out libpthread-2.23.so [.] __lll_lock_wait
+ 30.86% __lll_lock_wait
+ 4.53% 0xb8c80
- 20.51% 5.40% a.out [kernel.kallsyms] [k] futex_wake
+ 15.11% futex_wake
+ 5.40% 0xb8c80
- 19.41% 0.88% a.out [kernel.kallsyms] [k] futex_wait
+ 18.53% futex_wait
+ 0.88% 0xb8c80
- 16.92% 6.25% a.out [kernel.kallsyms] [k] _raw_spin_lock
+ 10.67% _raw_spin_lock
+ 6.25% 0xb8c80
- 12.77% 12.73% a.out libpthread-2.23.so [.] pthread_mutex_lock
12.73% 0xb8c80
pthread_mutex_lock
+ 11.80% 5.41% a.out [kernel.kallsyms] [k] futex_wait_setup
+ 11.05% 11.05% a.out [kernel.kallsyms] [k] syscall_return_via_sysret
+ 10.68% 10.67% a.out [kernel.kallsyms] [k] native_queued_spin_lock_slowpath
+ 7.69% 7.65% a.out libpthread-2.23.so [.] pthread_mutex_unlock
+ 7.36% 0.11% a.out [kernel.kallsyms] [k] wake_up_q
+ 7.17% 1.27% a.out [kernel.kallsyms] [k] try_to_wake_up
+ 4.42% 0.23% a.out [kernel.kallsyms] [k] futex_wait_queue_me
+ 4.17% 0.08% a.out [kernel.kallsyms] [k] schedule
+ 3.84% 0.75% a.out [kernel.kallsyms] [k] __schedule
+ 2.70% 0.01% a.out [kernel.kallsyms] [k] ttwu_do_activate
+ 2.49% 2.48% a.out [kernel.kallsyms] [k] get_futex_value_locked
+ 2.38% 0.11% a.out [kernel.kallsyms] [k] activate_task
+ 2.26% 0.15% a.out [kernel.kallsyms] [k] enqueue_task_fair
+ 1.88% 1.88% a.out [unknown] [k] 0xfffffe000000601b
+ 1.84% 0.15% a.out [kernel.kallsyms] [k] __task_rq_lock
+ 1.78% 1.78% a.out [unknown] [k] 0xfffffe000005e01b
+ 1.77% 1.77% a.out [unknown] [k] 0xfffffe000003201b
+ 1.67% 0.02% a.out [kernel.kallsyms] [k] deactivate_task
+ 1.66% 1.66% a.out [unknown] [k] 0xfffffe000008a01b
如何使用分析工具在我的实际程序中找出这种类型的热点。我不想每次都使用“binary chop comment”来解决它。谢谢!
最佳答案
perf
默认使用帧指针展开,速度快,但不可靠。即使您的应用程序没有省略帧指针,库也可能会。
或者,您可以将 --call-graph
与 dwarf
或 lbr
一起使用。
dwarf
在采样期间记录堆栈 block ,稍后对其进行评估。它可以提供更多细节,但会产生巨大的痕迹,并且可能会有更多的扰动。
lbr
需要在较新的 Intel 处理器上提供硬件支持。
它将显示如下内容:
99.25% 2.61% a.out a.out [.] thread_func
|
|--97.67%--thread_func
| |
| |--45.33%--pthread_mutex_lock@plt
| |
| |--28.65%--pthread_mutex_unlock@plt
| |
| |--18.88%--__pthread_mutex_lock
| | __lll_lock_wait
| |
| --4.75%--__pthread_mutex_unlock_usercnt
| __lll_unlock_wake
|
--0.72%--__pthread_mutex_lock
关于c++ - Ubuntu,如何找到内核工作繁重的程序的热点?似乎 kernel.kallsyms 中的函数没有标记为用户空间函数的子函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54290461/
start_kernel 函数中创建的kallsyms 在哪里?我的意思是我们在 start_kernel 函数中有很多函数调用。是否在那里创建了 kallsyms。如果不是,请指出它是在哪个函数调用
在 Linux 内核中,我想探测内核函数 effective_prio()。它定义为 static。当我在 kallsyms 中搜索它的符号时,我找不到它。 kallsyms 有内核函数的所有符号吗?
我正在编写有关低级内容的代码。我需要知道内核符号地址才能编写可靠的代码。所以我在 Ubuntu kernel-3.0.19 的用户模式下尝试读取 kallsyms。这是用户模式下的 kallsyms
我不想找到系统调用表的内核地址。我通常通过 grepping sys_call 来做到这一点但在一个系统中,我可以看到地址但在其他情况下,它不显示该条目。 root@ubuntu:~# cat /pr
为什么/proc/kallsyms 中的某些符号会重复?例如:我看到 _acpi_module_name、__this_module、cleanup_module、.LC0 重复多次。 为什么会这样?
我有一个关于 linux 内核的项目。我们不能编译 linux 内核,我们必须调用未导出的函数,但是这个函数可以在/proc/kallsyms 中找到。(我们可以得到函数的地址)。但是我们并不知道调用
我使用以下开关编译我的 C++ 代码: g++ -O0 -g -rdynamic -DNDEBUG -DARMA_NO_DEBUG -std=c++11 -pthread 链接器开关是: -lboos
符号 machine_power_off 在 /proc/kallsyms 中用“T”标记: $ grep -w machine_power_off /proc/kallsyms ffffffff81
具有繁重内核工作(锁定解锁)的多线程程序,尝试使用分析工具在我的代码中找到热点。 我写了一个最小的可重现程序。编译它。使用分析工具,如 perf 、 gprof 和调用堆栈记录。然后都不能在我的代码报
我从 this SO post 看到那/proc/kallsyms应该有动态加载模块的符号以及静态代码,而 System.map仅包含静态代码的符号。但是,当我 cat /proc/kallsyms我
/boot/System.map 和/proc/kallsyms 之间有一个固定的间隙。每次重启时差距都会改变。 有布局随机化之类的东西吗? 例如, > cat /boot/System.map ff
我只想知道 System.map 之间的区别文件和 /proc/kallsyms . 我正在使用 Linux 3.16 通用内核。我知道两者都是内核符号表。当我对这些文件进行比较时,两者都具有相同的内
我是一名优秀的程序员,十分优秀!