Установить сродство процессора для MATLAB engine (Windows 7)
Я разрабатываю приложение на C++. Один из компонентов приложения использует Matlab (через движок Matlab) для обработки данных. В то же время система сбора данных передает данные на диск. Иногда, в периоды интенсивной обработки Matlab, система сбора аварийно завершает работу. Установив сродство процессора Matlab к подмножеству доступных процессоров, эта проблема будет решена. Однако, как приложение запускается несколько раз в день, так и на несколько машины, вручную устанавливающие сродство каждый раз неудобно. Трюк установки сродства процессора через командную строку ярлыка не работает, так как движок запускается из моего приложения, а не через ярлык. Я искал способ программно установить сродство, но с ограниченным успехом.
Я рассмотрел следующие варианты (ранжированные в порядке предпочтения):
- укажите сродство процессора для движка matlab от в рамках приложения, когда двигатель запущен.
- укажите сродство процессора по умолчанию для движка matlab отдельно от полного приложения Matlab.
- в крайнем случае установите сродство по умолчанию для Matlab (как двигатель, так и не двигатель использует). Это наименее желательно, так как Matlab используется для других целей на машинах развертывания, и было бы предпочтительнее не ограничивать его для других применений.
можно ли установить сходство процессора из моего приложения, и если да, то как? Если нет, то как правильно решить эту проблему? Любые советы по этим вариантам или другие предложения/решения будут приветствоваться.
3 ответов
звучит так, как будто вы на Windows. Вы можете вызвать .NET непосредственно из Matlab для управления маской сходства процессора и избежать необходимости создавать файл MEX. система.Диагностика.Класс 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 предоставляет объекты библиотеки .NET standard в Windows, иногда можно найдите такие вопросы в C# или .NET и перенесите ответ непосредственно в Matlab.
Я не пробовал это решение, но, похоже, она должна работать. Создайте простую функцию mex, которая делает следующее:
- вызов
GetCurrentProcess
чтобы получить дескриптор для процесса MATLAB - установите соответствующую маску сродства для этого процесса с помощью
SetProcessAffinityMask
теперь, когда ваше приложение запускается, просто вызовите эту функцию mex, как обычную функцию MATLAB (функция mex должна быть видна на MATLAB path), и он должен установить сродство процессора, как вы хотите. Вы даже можете передать маску сродства в качестве входа в функцию, чтобы сделать ее более универсальной.
Ниже приведена реализация функции MEX, которая @Praetorian описал (показывает как использовать 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:
сродство процесса наследуется любым дочерним процессом или новым создается локальный процесс.
не называй
SetProcessAffinityMask
в DLL, который может быть вызван процессы, отличные от ваших собственных.
таким образом, возня с сродством повлияет на все вычисления, инициированные MATLAB и его зависимыми библиотеками. Вот a сообщение от Raymond Chen по теме.