gpt4 book ai didi

c++ - Ubuntu,如何找到内核工作繁重的程序的热点?似乎 kernel.kallsyms 中的函数没有标记为用户空间函数的子函数

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:03:55 24 4
gpt4 key购买 nike

具有繁重内核工作(锁定解锁)的多线程程序,尝试使用分析工具在我的代码中找到热点。

我写了一个最小的可重现程序。编译它。使用分析工具,如 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-graphdwarflbr 一起使用。

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/

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