我已经编写了一个Mex函数(可以从Matlab调用的C++函数),我想使用valgrind/kcachegrind对其进行概要分析。如果您直接运行c++程序,我知道如何使用valgrind/kcachegrind,但是如果我从Matlab调用c++程序,有没有办法进行此性能分析?
最佳答案
由于MEX文件是共享库,因此对MEX文件进行概要分析非常棘手。使用标准的“gprof”方法无法在Linux上完成-gprof根本不这样做。我尝试使用sprof,但得到了“PLTREL not found error”-sprof也不能使用。上一篇文章here,但没有人给出最终答案。
幸运的是,有一种方法可以在 Linux 上使用valgrind来完成。首先,我们需要编写“运行”代码来加载mex文件,提供供我们调用的mexFunction符号,并设置MEX文件的参数。我选择使用推荐的方法在MATLAB中执行此操作-使用MATLAB engine。以下代码(另存为test.c)加载MEX文件并查找mexFunction符号,从先前另存为“input.mat”的文件中加载输入数据(可以在MATLAB中使用save命令完成),并调用mexFunction。
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <dlfcn.h>
#include "engine.h"
typedef void (*mexFunction_t)(int nargout, mxArray *pargout [ ], int nargin, const mxArray *pargin[]);
int main(int argc, const char *argv[])
{
Engine *ep;
char buff[1024];
int i;
/* matlab must be in the PATH! */
if (!(ep = engOpen("matlab -nodisplay"))) {
fprintf(stderr, "Can't start MATLAB engine\n");
return -1;
}
engOutputBuffer(ep, buff, 1023);
/* load the mex file */
if(argc<2){
fprintf(stderr, "Error. Give full path to the MEX file as input parameter.\n");
return -1;
}
void *handle = dlopen(argv[1], RTLD_NOW);
if(!handle){
fprintf(stderr, "Error loading MEX file: %s\n", strerror(errno));
return -1;
}
/* grab mexFunction handle */
mexFunction_t mexfunction = (mexFunction_t)dlsym(handle, "mexFunction");
if(!mexfunction){
fprintf(stderr, "MEX file does not contain mexFunction\n");
return -1;
}
/* load input data - for convenience do that using MATLAB engine */
/* NOTE: parameters are MEX-file specific, so one has to modify this*/
/* to fit particular needs */
engEvalString(ep, "load input.mat");
mxArray *arg1 = engGetVariable(ep, "Ain");
mxArray *arg2 = engGetVariable(ep, "opts");
mxArray *pargout[1] = {0};
const mxArray *pargin[2] = {arg1, arg2};
/* execute the mex function */
mexfunction(1, pargout, 2, pargin);
/* print the results using MATLAB engine */
engPutVariable(ep, "result", pargout[0]);
engEvalString(ep, "result");
printf("%s\n", buff);
/* cleanup */
mxDestroyArray(pargout[0]);
engEvalString(ep, "clear all;");
dlclose(handle);
engClose(ep);
return 0;
}
MEX文件本身也应使用
mex -g
开关进行编译。上面的代码必须使用mex -g
进行编译,并使用engopts.sh作为编译参数。从MATLAB命令行类型mex('-v', '-f', fullfile(matlabroot,...
'bin','engopts.sh'),...
'test.c');
或在标准Linux终端中运行
/path/to/matlab/bin/mex -g -f /path/to/matlab/bin/engopts.sh test.c
使用valgrind对MEX文件进行性能分析需要从命令行运行“测试”程序。在测试和MEX文件所在的目录中,键入以下命令:
PATH=$PATH:/path/to/matlab/bin/ LD_LIBRARY_PATH=/path/to/matlab/bin/glnxa64/:/path/to/matlab/sys/os/glnxa64/ valgrind --tool=callgrind ./test ./mex_file.mexa64
请注意,需要设置MATLAB的路径以及与体系结构相关的正确库路径! matlab可执行文件必须存在于PATH中,否则“测试”将失败。
还有一个收获。 MATLAB引擎要求将csh安装在系统上(您可以使用任何shell,csh仅需要存在于/bin中)。因此,如果没有它,则必须安装它才能正常工作。
关于c++ - 如何在Matlab中配置MEX功能,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11220250/