簡體   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