【问题标题】:Set processor affinity for MATLAB engine (Windows 7)为 MATLAB 引擎设置处理器关联 (Windows 7)
【发布时间】:2012-04-04 10:01:12
【问题描述】:

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

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

  1. 在引擎启动时,从应用程序中为 matlab 引擎指定处理器亲和性。
  2. 为 matlab 引擎指定默认处理器关联,与完整的 Matlab 应用程序本身分开。
  3. 作为最后的手段,为 Matlab 设置默认关联(引擎和非引擎使用)。这是最不可取的,因为 Matlab 在部署机器上用于其他目的,最好不要将其限制为其他用途。

是否可以在我的应用程序中设置处理器关联,如果可以,如何设置?如果没有,解决这个问题的正确方法是什么?欢迎对这些选项或其他建议/解决方案提出任何建议。

【问题讨论】:

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


    【解决方案1】:

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

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

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

    【讨论】:

      【解决方案2】:

      听起来你在 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。

      【讨论】:

      • 谢谢。这正是我正在寻找的。​​span>
      【解决方案3】:

      下面是 @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 的主题。

      【讨论】:

        猜你喜欢
        • 2014-03-19
        • 2010-10-24
        • 2010-11-02
        • 2014-06-13
        • 2011-03-03
        • 1970-01-01
        • 1970-01-01
        • 2010-10-12
        • 2011-12-07
        相关资源
        最近更新 更多