[英]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.