我已经开始使用valgrind,特别是用于代码分析的工具“callgrind”。
为了开始,我创建了一个用于数值积分的共享库(我实现了一个抽象类接口和一些专门用于求积公式的派生类,例如Simpson,Trapezoidal,Midpoint)。在这一点上,我在应用程序中使用test库,我想使用callgrind来检测主要瓶颈并优化代码。
因此,我在调试模式下编译了可执行文件,并使用Kcachegrind分析了程序的行为。
我在主程序下面附上了:实质上,我创建了一个基类“NUMERICAL_INTEGRATION”,它是每个求积公式的模板,然后我测试了一些函数。
#include <stdio.h>
#include <iostream>
#include <functional>
#include "Quadrature.hpp"
//#include <matplot/matplot.h>
int main()
{
/*--- MODULE FOR NUMERICAL INTEGRATION --TESTING------- */
using namespace Integrate_1D;
NUMERICAL_INTEGRATION<MidPointQuadrature> nIntegrationMID;
NUMERICAL_INTEGRATION<GaussLegeandreQuadrature> nIntegrationGL;
NUMERICAL_INTEGRATION<SimpsonQuadrature> nIntegrationSIMPS;
NUMERICAL_INTEGRATION<TrapzQuadrature> nIntegrationTRAPZ;
// Example : Integration of f(x) = x:
// All the formulas has to be exact for this function:
auto ToIntegrate0 = [](double x)
{
return x;
};
double xSTART = 0.0;
double xEND = 2.0;
double EXACT_RES0 = 2.0;
unsigned int N0;
std::vector<double> degrees0;
std::vector<std::vector<double>> errors0_(3,std::vector<double>(4));
std::cout <<"********************************************\n";
std::cout<< " TESTING FOR f(x) =x \n";
std::cout<< "********************************************\n";
N0=2;
double MID_RES0 = nIntegrationMID(ToIntegrate0,xSTART,xEND,N0);
double TRPZ_RES0 = nIntegrationTRAPZ(ToIntegrate0,xSTART,xEND,N0);
double SIMPS_RES0 = nIntegrationSIMPS(ToIntegrate0,xSTART,xEND,N0);
double GL_RES0 = nIntegrationGL(ToIntegrate0,xSTART,xEND,N0);
std::cout << "********** TEST WITH N="<<N0<<"**************\n";
std::cout << "EXACT-RESULT of the integration: "<<EXACT_RES0 <<"\n";
std::cout << "Mid-point-result : " << MID_RES0 << "\n";
std::cout << "Trapezoidal-result : " << TRPZ_RES0 << "\n";
std::cout << "Simpson-result : " << SIMPS_RES0 << "\n";
std::cout << "Gauss-Legendre-result : "<< GL_RES0 << "\n";
errors0_[0][0] = abs(MID_RES0-EXACT_RES0);
errors0_[0][1]= abs(TRPZ_RES0-EXACT_RES0);
errors0_[0][2] = abs(SIMPS_RES0-EXACT_RES0);
errors0_[0][3] = abs(GL_RES0-EXACT_RES0);
std::cout << "***************************************\n";
N0=4;
MID_RES0 = nIntegrationMID(ToIntegrate0,xSTART,xEND,N0);
TRPZ_RES0 = nIntegrationTRAPZ(ToIntegrate0,xSTART,xEND,N0);
SIMPS_RES0 = nIntegrationSIMPS(ToIntegrate0,xSTART,xEND,N0);
GL_RES0 = nIntegrationGL(ToIntegrate0,xSTART,xEND,N0);
std::cout << "********** TEST WITH N="<<N0<<"**************\n";
std::cout << "EXACT-RESULT of the integration: "<<EXACT_RES0 <<"\n";
std::cout << "Mid-point-result : " << MID_RES0 << "\n";
std::cout << "Trapezoidal-result : " << TRPZ_RES0 << "\n";
std::cout << "Simpson-result : " << SIMPS_RES0 << "\n";
std::cout << "Gauss-Legendre-result : "<< GL_RES0 << "\n";
// Fill the error vector:
errors0_[1][0] = abs(MID_RES0-EXACT_RES0);
errors0_[1][1] = abs(TRPZ_RES0-EXACT_RES0);
errors0_[1][2] = abs(SIMPS_RES0-EXACT_RES0);
errors0_[1][3] = abs(GL_RES0-EXACT_RES0);
std::cout << "***************************************\n";
N0=8;
MID_RES0 = nIntegrationMID(ToIntegrate0,xSTART,xEND,N0);
TRPZ_RES0 = nIntegrationTRAPZ(ToIntegrate0,xSTART,xEND,N0);
SIMPS_RES0 = nIntegrationSIMPS(ToIntegrate0,xSTART,xEND,N0);
GL_RES0 = nIntegrationGL(ToIntegrate0,xSTART,xEND,N0);
std::cout << "********** TEST WITH N="<<N0<<"**************\n";
std::cout << "EXACT-RESULT of the integration: "<<EXACT_RES0 <<"\n";
std::cout << "Mid-point-result : " << MID_RES0 << "\n";
std::cout << "Trapezoidal-result : " << TRPZ_RES0 << "\n";
std::cout << "Simpson-result : " << SIMPS_RES0 << "\n";
std::cout << "Gauss-Legendre-result : "<< GL_RES0 << "\n";
std::cout << "ERROR FOR N=8 : f(x)=x" <<std::endl;
std::cout << "trapz: " << TRPZ_RES0-EXACT_RES0<<std::endl;
std::cout << "midpoint: " << MID_RES0-EXACT_RES0<<std::endl;
std::cout << "simpson: " << SIMPS_RES0-EXACT_RES0<<std::endl;
std::cout << "GaussLegendre: " << GL_RES0-EXACT_RES0<<std::endl;
std::cout << "******************************************\n";
std::cout << "******************************************\n";
std::cout << "*******END TEST FOR f(x) = x *********\n\n\n\n";
// Example : Integration of f(x) = sin(x):
auto ToIntegrate = [](double x)
{
return sin(x);
};
xSTART = 0.0;
xEND = M_PI;
unsigned int N;
std::vector<double> degrees;
std::vector<std::vector<double>> errors_(4,std::vector<double>(4));
std::vector<double> currErrors(4);
double EXACT_RES = 2.0;
std::cout <<"********************************************\n";
std::cout<< " TESTING FOR f(x) = sin(x) \n";
std::cout<< "********************************************\n";
N=2;
degrees.push_back(double(N));
double MID_RES = nIntegrationMID(ToIntegrate,xSTART,xEND,N);
double TRPZ_RES = nIntegrationTRAPZ(ToIntegrate,xSTART,xEND,N);
double SIMPS_RES = nIntegrationSIMPS(ToIntegrate,xSTART,xEND,N);
double GL_RES = nIntegrationGL(ToIntegrate,xSTART,xEND,N);
std::cout << "********** TEST WITH N="<<N<<"**************\n";
std::cout << "EXACT-RESULT of the integration: "<<EXACT_RES <<"\n";
std::cout << "Mid-point-result : " << MID_RES << "\n";
std::cout << "Trapezoidal-result : " << TRPZ_RES << "\n";
std::cout << "Simpson-result : " << SIMPS_RES << "\n";
std::cout << "Gauss-Legendre-result : "<< GL_RES << "\n";
errors_[0][0] = abs(MID_RES-EXACT_RES);
errors_[0][1]= abs(TRPZ_RES-EXACT_RES);
errors_[0][2] = abs(SIMPS_RES-EXACT_RES);
errors_[0][3] = abs(GL_RES-EXACT_RES);
std::cout << "***************************************\n";
N=4;
degrees.push_back(double(N));
MID_RES = nIntegrationMID(ToIntegrate,xSTART,xEND,N);
TRPZ_RES = nIntegrationTRAPZ(ToIntegrate,xSTART,xEND,N);
SIMPS_RES = nIntegrationSIMPS(ToIntegrate,xSTART,xEND,N);
GL_RES = nIntegrationGL(ToIntegrate,xSTART,xEND,N);
std::cout << "********** TEST WITH N="<<N<<"**************\n";
std::cout << "EXACT-RESULT of the integration: "<<EXACT_RES <<"\n";
std::cout << "Mid-point-result : " << MID_RES << "\n";
std::cout << "Trapezoidal-result : " << TRPZ_RES << "\n";
std::cout << "Simpson-result : " << SIMPS_RES << "\n";
std::cout << "Gauss-Legendre-result : "<< GL_RES << "\n";
// Fill the error vector:
errors_[1][0] = abs(MID_RES-EXACT_RES);
errors_[1][1] = abs(TRPZ_RES-EXACT_RES);
errors_[1][2] = abs(SIMPS_RES-EXACT_RES);
errors_[1][3] = abs(GL_RES-EXACT_RES);
std::cout << "***************************************\n";
N=5;
degrees.push_back(double(N));
MID_RES = nIntegrationMID(ToIntegrate,xSTART,xEND,N);
TRPZ_RES = nIntegrationTRAPZ(ToIntegrate,xSTART,xEND,N);
SIMPS_RES = nIntegrationSIMPS(ToIntegrate,xSTART,xEND,N);
GL_RES = nIntegrationGL(ToIntegrate,xSTART,xEND,N);
std::cout << "********** TEST WITH N="<<N<<"**************\n";
std::cout << "EXACT-RESULT of the integration: "<<EXACT_RES <<"\n";
std::cout << "Mid-point-result : " << MID_RES << "\n";
std::cout << "Trapezoidal-result : " << TRPZ_RES << "\n";
std::cout << "Simpson-result : " << SIMPS_RES << "\n";
std::cout << "Gauss-Legendre-result : "<< GL_RES << "\n";
// Fill the error vector:
errors_[2][0] = abs(MID_RES-EXACT_RES);
errors_[2][1] = abs(TRPZ_RES-EXACT_RES);
errors_[2][2] = abs(SIMPS_RES-EXACT_RES);
errors_[2][3] = abs(GL_RES-EXACT_RES);
std::cout << "***************************************\n";
N=8;
degrees.push_back(double(N));
MID_RES = nIntegrationMID(ToIntegrate,xSTART,xEND,N);
TRPZ_RES = nIntegrationTRAPZ(ToIntegrate,xSTART,xEND,N);
SIMPS_RES = nIntegrationSIMPS(ToIntegrate,xSTART,xEND,N);
GL_RES = nIntegrationGL(ToIntegrate,xSTART,xEND,N);
std::cout << "********** TEST WITH N="<<N<<"**************\n";
std::cout << "EXACT-RESULT of the integration: "<<EXACT_RES <<"\n";
std::cout << "Mid-point-result : " << MID_RES << "\n";
std::cout << "Trapezoidal-result : " << TRPZ_RES << "\n";
std::cout << "Simpson-result : " << SIMPS_RES << "\n";
std::cout << "Gauss-Legendre-result : "<< GL_RES << "\n";
// Fill the error vector:
errors_[3][0] = abs(MID_RES-EXACT_RES);
errors_[3][1] = abs(TRPZ_RES-EXACT_RES);
errors_[3][2] = abs(SIMPS_RES-EXACT_RES);
errors_[3][3] = abs(GL_RES-EXACT_RES);
std::cout << "***************************************\n";
std::vector<double> mid_error = {errors_[0][0],errors_[1][0],errors_[2][0],errors_[3][0]};
std::vector<double> trz_error = {errors_[0][1],errors_[1][1],errors_[2][1],errors_[3][1]};
std::vector<double> simps_error = {errors_[0][2],errors_[1][2],errors_[2][2],errors_[3][2]};
std::vector<double> gl_error = {errors_[0][3],errors_[1][3],errors_[2][3],errors_[3][3]};
字符串
现在,问题是,当我尝试使用valgrind。
附件中你可以找到一个屏幕截图,显示了该程序(kcachegrind)的主要用途。
首先,我不明白什么是_dl_start,为什么它需要相对总成本的82%。有人能给予我一些解释吗?
第二个问题是:代码分析和优化代码的最佳实践是什么?特别是,有一些指导方针可以检测主要瓶颈并使代码更快?
抱歉,如果我太笼统,但我是新来的,我不知道的东西在具体的。
谢谢大家的回答。
valgrind: kcachegrind
2条答案
按热度按时间qyzbxkaa1#
_dl_start
是“动态库”代码,用于加载共享库并执行符号的运行时链接。如果你在这些例程上花费了超过80%的时间,那么你的测试程序肯定只是在做一些微不足道的事情。你需要做一个更大的测试,这样callgrind就有更多的东西要测量。或者,你需要使用客户端请求机制。你可以使用这个机制,callgrind不会检测任何东西,直到你告诉它,这将是你想要分析的函数。如果你有一个小的测试用例,这将允许你从谷壳中挑选小麦。
hwamh0ep2#
Valgrind是一个强大的工具,用于检测C和C++程序中的内存泄漏,内存损坏和其他内存相关问题。要使用Valgrind执行良好的代码分析,请按照以下步骤操作:
1.安装Valgrind:
确保Valgrind已安装在您的系统上。您可以使用特定于您的操作系统的软件包管理器安装它。例如,在基于Debian的系统上:
sudo apt-get install valgrind
2.使用编译符号编译代码:
确保您的代码使用调试符号(-g标志)进行编译,以从Valgrind获得更准确和信息丰富的结果。
gcc -g -o your_program your_source_code.c
3.内存泄漏检测:
使用Valgrind运行你的程序来检测内存泄漏。Valgrind的memcheck工具通常用于此目的。
valgrind --leak-check=full ./your_program
--leak-check=full:提供有关内存泄漏的详细信息。检查Valgrind输出是否有任何报告的内存泄漏。它将提供有关内存分配位置和丢失位置的信息。
4.地址和内存错误:
Valgrind的memcheck工具还有助于检测内存损坏和其他与内存相关的错误。
valgrind --tool=memcheck --track-origins=yes ./your_program
--tool=memcheck:使用memcheck工具。--track-origins=yes:尝试显示未初始化值的来源。检查Valgrind输出中的任何报告错误,并在代码中解决它们。
5.分析调用:
Valgrind的callgrind工具可以用于代码分析,以识别热点和测量函数调用频率。
valgrind --tool=callgrind ./your_program
这将生成一个callgrind.out文件。
kcachegrind callgrind. out. *
kcachegrind callgrind. out. *
温馨提示:
**抑制文件:**您可能会在第三方库中遇到误报或不相关的问题。请创建抑制文件以从Valgrind输出中排除特定问题。
**Valgrind选项:**Valgrind提供各种自定义选项。根据您的需求查看文档以获取其他选项。
**迭代过程:**一次解决一个问题,重新运行Valgrind以确保您取得进展。
通过遵循这些步骤,您可以有效地使用Valgrind分析您的C或C++代码,识别与内存相关的问题,并提高软件的整体质量。