繁体   English   中英

如何在Matlab中分析MEX函数

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

我有一个Mex函数(c ++函数,你可以从Matlab调用),我已经编写了,我想用valgrind / kcachegrind来描述它。 如果你直接运行一个c ++程序,我知道如何使用valgrind / kcachegrind,但如果我从Matlab调用c ++程序,有没有办法进行这种分析?

由于MEX文件是共享库,因此分析MEX文件很棘手。 使用标准的'gprof'方法无法在Linux上完成 - gprof根本不这样做。 我试图使用sprof,但我得到“PLTREL not found error” - sprof也不能使用。 有一前一后在这里 ,也没有人给一个最终的答案。

幸运的是,有一种方法可以在Linux上使用valgrind来实现。 首先,我们需要编写“运行”代码来加载mex文件,提供mexFunction符号供我们调用,并设置MEX文件的参数。 我选择使用推荐的方法用MATLAB做 - 使用MATLAB引擎 以下代码(另存为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;
}

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文件需要从命令行运行'test'程序。 在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

请注意,需要设置MATLAB的路径和正确的体系结构相关库路径! matlab可执行文件必须存在于PATH中,否则'test'将失败。

还有一个问题。 MATLAB引擎需要在系统上安装csh(你可以使用任何shell,csh只需要存在于/ bin中)。 所以如果你没有它,你必须安装它才能工作。

您可以使用-D选项启动MATLAB,如此MatlabCentral线程中所述

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

我想补充一下,确保你有最新版本的valgrind。 当我尝试使用valgrind版本3.6调试我的MEX文件时,valgrind崩溃而不是报告内存错误。

暂无
暂无

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

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