为MATLAB引擎设置处理器关联(Windows 7)

时间:2012-03-19 21:32:26

标签: c++ matlab windows-7 affinity matlab-engine

我正在用c ++开发一个应用程序。该应用程序的一个组件使用Matlab(通过Matlab引擎)进行数据处理。同时,数据采集系统将数据流传输到磁盘。偶尔,在强化Matlab处理期间,采集系统崩溃。通过将Matlab的处理器亲和性设置为可用处理器的子集,可以解决此问题。但是,由于应用程序每天启动几次,并且在多台计算机上,每次手动设置关联性都很不方便。通过快捷方式的命令行设置处理器关联性的技巧不起作用,因为引擎是从我的应用程序内启动的,而不是通过快捷方式启动的。我一直在寻找一种以编程方式设置亲和力的方法,但成效有限。

我考虑了以下选项(按优先顺序排列):

  1. 在引擎启动时,从应用程序中指定matlab引擎的处理器关联。
  2. 指定matlab引擎的默认处理器关联,与完整的Matlab应用程序本身分开。
  3. 作为最后的手段,为Matlab设置默认关联(引擎和非引擎使用)。这是最不可取的,因为Matlab在部署机器上用于其他目的,并且最好不要将其限制在其他用途​​中。
  4. 是否可以在我的应用程序中设置处理器关联,如果可以,如何设置?如果没有,解决这个问题的正确方法是什么?有关这些选项或其他建议/解决方案的任何建议都将受到欢迎。

3 个答案:

答案 0 :(得分:6)

听起来像是在Windows上。您可以直接从Matlab调用.NET来操作处理器关联掩码,并避免构建MEX文件。 System.Diagnostics.Process类具有处理器关联性的控件,如in this solution所述。这是一个使用它的Matlab函数。启动它后,首先在Matlab引擎中运行它。

function twiddle_processor_affinity()
proc = System.Diagnostics.Process.GetCurrentProcess();
aff = proc.ProcessorAffinity.ToInt32;  % get current affinity mask
fprintf('Current affinity mask: %s\n', dec2bin(aff, 8));
proc.ProcessorAffinity = System.IntPtr(int32(2)); % set affinity mask
fprintf('Adjusted affinity to: %s\n', dec2bin(proc.ProcessorAffinity.ToInt32, 8));

由于Matlab在Windows上公开.NET标准库对象,您有时可以在C#或.NET下搜索这样的问题,并将答案直接传递给Matlab。

答案 1 :(得分:4)

我没有尝试过这个解决方案,但它似乎应该可行。创建一个简单的mex函数,执行以下操作:

  1. 调用GetCurrentProcess以检索MATLAB过程的句柄
  2. 使用SetProcessAffinityMask
  3. 为此流程设置适当的关联掩码

    现在,当您的应用程序启动时,只需调用此mex函数,就像调用常规MATLAB函数一样(mex函数必须在MATLAB路径上可见),并且应根据需要设置处理器关联。您甚至可以将亲和力掩码作为函数的输入传递给它,以使其更加通用。

答案 2 :(得分:0)

以下是@Praetorian described(显示how to use the SetProcessAffinityMask function)的MEX函数的实现:

set_affinity.c

#include "mex.h"
#include <windows.h>

void mexFunction(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
{
    HANDLE hProc;
    DWORD_PTR dwAffinityMask;
    unsigned int numCores;

    // check arguments
    if (nlhs > 0 || nrhs != 1) {
        mexErrMsgIdAndTxt("mex:error", "Wrong number of arguments.");
    }
    if (!mxIsDouble(prhs[0]) || mxGetNumberOfElements(prhs[0])!=1) {
        mexErrMsgIdAndTxt("mex:error", "Expecting a scalar number.");
    }

    // number of logical processors
    numCores = (unsigned int) mxGetScalar(prhs[0]);

    // set affinity of current process to use all cores
    hProc = GetCurrentProcess();
    dwAffinityMask = (1 << numCores) - 1;
    if (!SetProcessAffinityMask(hProc, dwAffinityMask)) {
        mexErrMsgIdAndTxt("mex:error", "WinAPI error code: %lu", GetLastError());
    }
}

实施例

在我的四核超线程机器上,我将调用MEX函数,如下所示,以允许MATLAB在所有8个逻辑处理器上执行:

>> getenv('NUMBER_OF_PROCESSORS')
ans =
8

>> mex -largeArrayDims set_affinity.c
>> set_affinity(8)

仅使用处理器数量的一半:

>> set_affinity(4)

请注意MSDN doc page中的以下注释:

  

进程关联性由任何子进程或新进程继承   实例化的本地流程。

     

不要在可能被调用的DLL中调用SetProcessAffinityMask   除了你自己以外的其他过程。

因此,使用关联性会影响MATLAB及其依赖库启动的所有计算。这是关于该主题的a post by Raymond Chen