繁体   English   中英

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

[英]Set processor affinity for MATLAB engine (Windows 7)

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

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

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

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

听起来你在 Windows 上。 您可以直接从 Matlab 调用 .NET 来操作处理器关联掩码,而不必构建 MEX 文件。 System.Diagnostics.Process 类具有对处理器关联的控制,如本解决方案中所述 这是一个使用它的 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。

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

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

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

下面是@Praetorian 描述的 MEX 函数的实现(展示了如何使用SetProcessAffinityMask函数):

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 文档页面中的以下注释:

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

不要在可能由您自己以外的进程调用的 DLL 中调用SetProcessAffinityMask

因此,弄乱亲和性将影响由 MATLAB 及其依赖库启动的所有计算。 这是Raymond Chen关于该主题的帖子

暂无
暂无

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

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