C++/Mex 包装器为在 WinXP 下的 Matlab 添加了微秒分辨率计时器






4.29/5 (3投票s)
2005年8月25日
1分钟阅读

46967

332
C++/Mex 包装器为在 WinXP 下的 Matlab 添加了微秒分辨率计时器。
引言
对于任何对性能感兴趣的 Matlab 用户来说,缺乏具有微秒分辨率的精确计时器是一个主要缺点。在 Linux 下,有可用的内核补丁提供此功能,但在 Windows 下,只能使用毫秒分辨率。幸运的是,Keith Wansbrough 将他的 TSCtime 包 投入公共领域,从而在 Visual C++ 下为 C/C++ 程序提供精确计时。
Mex 包装器实现
该项目包含一个 Mex 包装器函数,用于从 Matlab 内部访问 Keith Wansbrough 的 TSCtime 高精度时间测量函数。Matlab 通过调用编译此项目文件生成的 mex_tsctimer.dll 来实现这一点。
此 DLL 支持的封装的 TSCtime 函数包括
recalibrate();
gethectonanotime_first();
gethectonanotime_last();
从 Matlab 传递一个参数来选择要调用所需的 TSCtime 函数的封装函数,从而避免为每个函数创建单独的 DLL 文件。
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { const char str[]="Function 'mexeval' not defined for variables of class"; char errMsg[100]; // const mxArray *in_data; int select = 0; // ULONGLONG t_meas = 0; double *outArray; //mexPrintf("executing mex_tsctimer(%d)\n", nrhs); // if(nrhs==0) { sprintf(errMsg,"%s '%s'\n",str,"double"); mexErrMsgTxt(errMsg); } else { // causes MATLAB to execute the string as an expression // in_data = prhs[0]; select = (int)(mxGetScalar(prhs[0])); //mexPrintf("%d selects %s\n", select, msg[select]); // if (select == 0) recalibrate(); else if (select == 1) t_meas = gethectonanotime_first(); else if (select == 2) t_meas = gethectonanotime_last(); // plhs[0] = mxCreateDoubleMatrix(1,1,mxREAL); outArray = mxGetPr(plhs[0]); outArray[0] = ((double)t_meas)/1e7; // //mexPrintf("measured time %f = %f\n", outArray[0], ((double)t_meas)/1e7); // } }
安装 Matlab DLL
只需将 mex_tsctimer.dll 复制到您的 Matlab 安装目录,或者将 Release 目录添加到您的 Windows 路径中,您就可以开始使用计时器了。
在 Matlab 中的用法
在使用 Matlab 或 C/C++ 中的 TSCtime 函数之前,您需要使用 Keith 提供的 TSCcal 实用程序校准计时器。
再次,对于那些对 Keith 代码的细节感兴趣的人,请参考他网站上的优秀解释 网站。
此实用程序将特定于您平台的计时器校准数据写入 Windows 注册表,随后 TSCtime 例程读取该数据以校正用户应用程序中测量的计时信息。
这是一个使用 DLL 在 Matlab 中测量稀疏矩阵与向量乘法的运行时间的示例
smvm_start = mex_tsctimer(1); % TSCtime : gethectonanotime_first()
b = A*x; % code whose execution time you want to measure
end_smvm= mex_tsctimer(2); % TSCtime : gethectonanotime_last()
run_time= end_smvm-smvm_start;