我已经创建了一个共享库,我现在需要对其进行分析。我现在有两个项目。一个生成共享库,另一个使用它进行测试。
int main() {
cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!!
MatrixXd frames = creatMatriXdromVtdFile("/home/michael/Dropbox/Java_Workspace/test/frame.vtd");
// MatrixXd frame = frames.row(0).array();
auto start = std::chrono::system_clock::now();
MatrixXd m = demodulateMatrix(frames.data(), frames.rows(), frames.cols());
auto end = std::chrono::system_clock::now();
auto elapsed =
std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
cout << "Demodulated all data in ";
cout << elapsed;
cout << " us \n";
cout << m.row(1);
return 0;
}
这基本上是第二个项目。在用gprof进行分析之后,我甚至不知道输出中的demodulateMatrix函数。
如何获取有关共享库中发生的事情的信息(如何分配内存,哪些功能需要花费时间等)?
答案 0 :(得分:2)
gprof 是一个值得尊敬且开创性的工具。
但你发现它非常有限。 它基于对程序计数器的采样,以及计算函数之间的调用,所有这些都与成本时间有着非常微弱的联系。
要了解程序中的时间成本,实际上非常简单。 The method I and others use is this
关键是,当程序运行时,有一个调用堆栈,由当前程序计数器和一个返回地址组成,返回到当前正在执行的每个函数调用指令,在线程上。
如果你可以在一个随机的时间点拍摄调用堆栈的X-Ray快照,并在调试器的上下文中检查它的所有级别,你可以确切地知道它正在尝试做什么,以及为什么,在那个时间点。
如果它花费30%的时间做一些你从未猜到过的事情,但你真的不需要,你会发现它有10个堆栈样本中的3个,或多或少,这就足够了找到它。 你不会确切知道百分比是多少,但你会确切地知道问题是什么。
任何指令花费的时间(如果你摆脱它,你节省的时间)只是它在堆栈上的时间百分比,无论是非调用指令还是调用指令。 如果它需要花费足够的时间来进行修复,它将显示在适量的样本中。
补充:不要强调这一点,但总会有人说“样本太少,会找到错误的东西!” 好吧,好吧。假设您需要十个随机时间的堆栈样本,并且您可以看到其中三个可以摆脱的东西。 它要多少钱? 嗯,你不确定。它的概率分布看起来完全如下:
你可以看到最可能的成本是30%(毫不奇怪),加速10/7 = 1.4x,但它会或多或少。 或多或少多少? 那么,两个阴影区域之间的清晰空间占概率的95%。 换句话说,是的,成本可能低于10%,即约2.5%。 如果成本是10%,则加速是10/9 = 1.1x。 另一方面,成本高于60%的概率相等,加速度为10/4 = 2.5x。
所以估计的加速比是1.4,但是虽然它可能低至1.1,但是不要丢掉它可能高达2.5的平等机会。 当然,如果你取20个样本而不是10个样本,曲线就会变窄。