简体   繁体   English

如何在Matlab中分析MEX函数

[英]How do I profile a MEX-function in Matlab

I have a Mex-function (a function in c++ that you can call from Matlab) that I have written, and I want to profile it using valgrind/kcachegrind. 我有一个Mex函数(c ++函数,你可以从Matlab调用),我已经编写了,我想用valgrind / kcachegrind来描述它。 I know how to use valgrind/kcachegrind if you are running a c++ program directly, but is there a way to do this profiling if I am calling the c++ program from Matlab? 如果你直接运行一个c ++程序,我知道如何使用valgrind / kcachegrind,但如果我从Matlab调用c ++程序,有没有办法进行这种分析?

Profiling MEX files is tricky since the MEX files are shared libraries. 由于MEX文件是共享库,因此分析MEX文件很棘手。 It can not be done on Linux using standard 'gprof' approach - gprof simply does not do that. 使用标准的'gprof'方法无法在Linux上完成 - gprof根本不这样做。 I tried to use sprof, but I get “PLTREL not found error” - sprof can not be used either. 我试图使用sprof,但我得到“PLTREL not found error” - sprof也不能使用。 There is a previous post here , but no one gave a final answer. 有一前一后在这里 ,也没有人给一个最终的答案。

Luckily, there is a way in which one can do it with valgrind on Linux . 幸运的是,有一种方法可以在Linux上使用valgrind来实现。 First, we need to write 'running' code that loads the mex file, provides the mexFunction symbol for us to call, and sets up the parameters of the MEX file. 首先,我们需要编写“运行”代码来加载mex文件,提供mexFunction符号供我们调用,并设置MEX文件的参数。 I have chosen to use the recommended way to do this with MATLAB - using MATLAB engine . 我选择使用推荐的方法用MATLAB做 - 使用MATLAB引擎 The following code (save as test.c) loads a MEX file and finds the mexFunction symbol, loads input data from a file previously saved as 'input.mat' (can be done in MATLAB using save command), and calls the mexFunction. 以下代码(另存为test.c)加载MEX文件并查找mexFunction符号,从先前保存为'input.mat'的文件中加载输入数据(可以使用save命令在MATLAB中完成),并调用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;
}

The MEX file itself should also compiled with the mex -g switch. MEX文件本身也应该用mex -g开关编译。 The above code has to be compiled with mex -g and using engopts.sh as compilation parameters. 上面的代码必须用mex -g编译并使用engopts.sh作为编译参数。 From MATLAB command line type 从MATLAB命令行类型

mex('-v', '-f', fullfile(matlabroot,...
    'bin','engopts.sh'),...
    'test.c');

or in a standard Linux terminal run 或者在标准的Linux终端运行中

/path/to/matlab/bin/mex -g -f /path/to/matlab/bin/engopts.sh test.c

Profiling the MEX file with valgrind requires running the 'test' program from the command line. 使用valgrind分析MEX文件需要从命令行运行'test'程序。 In the directory where both test and the MEX file reside type the command: 在test和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

Note that the path to MATLAB and correct architecture-dependent library paths need to be set! 请注意,需要设置MATLAB的路径和正确的体系结构相关库路径! matlab executable must be present in the PATH, otherwise 'test' will fail. matlab可执行文件必须存在于PATH中,否则'test'将失败。

There is one more catch. 还有一个问题。 MATLAB engine requires csh to be installed on the system (you can use any shell, csh just needs to be present in /bin). MATLAB引擎需要在系统上安装csh(你可以使用任何shell,csh只需要存在于/ bin中)。 So if you don't have it, you have to install it for this to work. 所以如果你没有它,你必须安装它才能工作。

You could start MATLAB with the -D option, as described on this MatlabCentral thread : 您可以使用-D选项启动MATLAB,如此MatlabCentral线程中所述

matlab -nojvm -nodesktop -nosplash -D"valgrind --error-limit=no --leak-check=yes --tool=memcheck -v --log-file=valgrind.log"

I would add to make sure that you have the latest version of valgrind. 我想补充一下,确保你有最新版本的valgrind。 When I tried to debug my MEX file with valgrind version 3.6, valgrind crashed instead of reporting memory errors. 当我尝试使用valgrind版本3.6调试我的MEX文件时,valgrind崩溃而不是报告内存错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM