[英]Set processor affinity for MATLAB engine (Windows 7)
我正在用 C++ 開發一個應用程序。 應用程序的組件之一使用 Matlab(通過 Matlab 引擎)進行數據處理。 同時,數據采集系統正在將數據流式傳輸到磁盤。 有時,在密集的 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 函數,它執行以下操作:
GetCurrentProcess
以檢索 MATLAB 進程的句柄SetProcessAffinityMask
為該進程設置適當的關聯掩碼現在,當您的應用程序啟動時,只需像調用常規 MATLAB 函數一樣調用此 mex 函數(該 mex 函數必須在 MATLAB 路徑上可見),它應該根據需要設置處理器關聯。 您甚至可以將親和掩碼作為輸入傳遞給函數,以使其更加通用。
下面是@Praetorian 描述的 MEX 函數的實現(展示了如何使用SetProcessAffinityMask
函數):
#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.