我正在尝试使用gperftools来分析多线程工作负载,但是难以解释所产生的输出。我编写了一个简单的程序,它启动了两个具有相同工作负载的线程,并使用gperftools cpu profiler进行了分析。在输出中,我可以看到每个线程的两个函数,但是每个线程的开销在一次运行到另一次运行时变化很大。我希望这两个函数显示相同的结果,因为它们是相同的工作负载,但实际上,一个可能是90%,另一个可能是10%,有时是80%/ 20%,95%/ 5%等等。我不这样做理解为什么函数显示不同的开销,或者为什么结果从一次运行到下一次运行的变化如此之大。基准测试运行约5秒钟,有1600个样本,所以应该是稳定的。
是否有任何文档可以解释分析如何适用于多线程工作负载以及如何解释输出?例如,探查器是否为每个样本上的每个线程执行回溯,如果没有,它在做什么?
#include <vector>
#include <cstdlib>
#include <thread>
using namespace std;
void thread_func() {
int size = 500000;
vector<int> V(size);
for(int i = 0; i < 100000; i++) {
V.erase(V.begin() + (rand() % size));
V.insert(V.begin() + (rand() % size), rand() % 10);
}
}
void thread_func2() {
int size = 500000;
vector<int> V(size);
for(int i = 0; i < 100000; i++) {
V.erase(V.begin() + (rand() % size));
V.insert(V.begin() + (rand() % size), rand() % 10);
}
}
int main() {
srand(1234);
thread t1(thread_func);
thread t2(thread_func2);
t1.join();
t2.join();
return 0;
}
示例输出:
0 0.0% 100.0% 1429 89.3% thread_func
0 0.0% 100.0% 172 10.7% thread_func2
89.3%和10.7%来自哪里? (这些是函数及其被调用者中总样本的百分比)
答案 0 :(得分:2)
这是SIGPROF信号传递的已知问题。有关详细信息,请参阅https://github.com/golang/go/issues/14434。
Gperftools实际上有#34;修复&#34;歪曲(如该问题所述)。您只需设置CPUPROFILE_PER_THREAD_TIMERS = t并确保链接librt和libpthread。而且你还需要注册&#34;你的主题或LD_PRELOAD https://github.com/alk/gperf-all-threads