解释 gperftools 在多线程工作负载上的结果
Interpreting results for gperftools on multi-threaded workloads
我正在尝试使用 gperftools 分析多线程工作负载,但在解释生成的输出时遇到困难。我编写了一个简单的程序,它启动两个具有相同工作负载的线程,并使用 gperftools cpu 分析器进行分析。在输出中,我可以看到每个线程的两个函数,但每个线程的开销与下一个 运行 相差很大。我希望这两个函数显示相同的结果,因为它们是相同的工作负载,但实际上,一个可能是 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% 来自哪里? (这些是函数及其调用者中样本总数的百分比)
Image contains a portion of the graph, numbers are slightly different from above because it's a different run
这是 SIGPROF 信号传递的已知问题。有关详细信息,请参阅 https://github.com/golang/go/issues/14434。
Gperftools 实际上有 "fix" 的偏差(如该问题所述)。您只需要设置 CPUPROFILE_PER_THREAD_TIMERS=t 并确保链接了 librt 和 libpthread。你还需要 "register" 你的线程或 LD_PRELOAD https://github.com/alk/gperf-all-threads
我正在尝试使用 gperftools 分析多线程工作负载,但在解释生成的输出时遇到困难。我编写了一个简单的程序,它启动两个具有相同工作负载的线程,并使用 gperftools cpu 分析器进行分析。在输出中,我可以看到每个线程的两个函数,但每个线程的开销与下一个 运行 相差很大。我希望这两个函数显示相同的结果,因为它们是相同的工作负载,但实际上,一个可能是 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% 来自哪里? (这些是函数及其调用者中样本总数的百分比)
Image contains a portion of the graph, numbers are slightly different from above because it's a different run
这是 SIGPROF 信号传递的已知问题。有关详细信息,请参阅 https://github.com/golang/go/issues/14434。
Gperftools 实际上有 "fix" 的偏差(如该问题所述)。您只需要设置 CPUPROFILE_PER_THREAD_TIMERS=t 并确保链接了 librt 和 libpthread。你还需要 "register" 你的线程或 LD_PRELOAD https://github.com/alk/gperf-all-threads