Установить привязку процессора к движку MATLAB (Windows 7) - PullRequest
7 голосов
/ 20 марта 2012

Я занимаюсь разработкой приложения на с ++. Один из компонентов приложения использует Matlab (через механизм Matlab) для обработки данных. В то же время система сбора данных осуществляет потоковую передачу данных на диск. Иногда в периоды интенсивной обработки Matlab происходит сбой системы сбора данных. Путем установки соответствия процессоров Matlab подмножеству доступных процессоров эта проблема решается. Однако, так как приложение запускается несколько раз в день и на нескольких компьютерах, ручная настройка привязки каждый раз неудобна. Уловка установки соответствия процессора через командную строку ярлыка не работает, так как движок запускается из моего приложения, а не через ярлык. Я искал способ программно установить сродство, но с ограниченным успехом.

Я рассмотрел следующие варианты (ранжированные в порядке предпочтения):

  1. Укажите привязку процессора к движку Matlab из приложения при запуске.
  2. Укажите привязку процессора по умолчанию для механизма Matlab отдельно от самого полного приложения Matlab.
  3. В качестве крайней меры установите сходство по умолчанию для Matlab (как для двигателей, так и для других машин) Это наименее желательно, поскольку Matlab используется для других целей на машинах развертывания, и было бы предпочтительно не ограничивать его для других целей.

Можно ли установить привязку процессора в моем приложении, и если да, то как? Если нет, как правильно решить эту проблему? Любые советы по этим вариантам или другие предложения / решения будут приветствоваться.

Ответы [ 3 ]

6 голосов
/ 20 марта 2012

Звучит так, будто вы в Windows.Вы можете вызывать .NET напрямую из Matlab, чтобы манипулировать маской сродства процессора и избежать создания файла 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 предоставляет объекты стандартной библиотеки .NET в Windows, вы можете иногда искать такие вопросы в C # или .NET и переносить ответпрямо к Matlab.

4 голосов
/ 20 марта 2012

Я не пробовал это решение, но похоже, что оно должно работать.Создайте простую функцию mex, которая выполняет следующие действия:

  1. Вызовите GetCurrentProcess, чтобы получить дескриптор процесса MATLAB
  2. Установите соответствующую маску соответствия для этогопроцесс с использованием SetProcessAffinityMask

Теперь, когда ваше приложение запускается, просто вызовите эту функцию mex, как если бы вы работали с обычной функцией MATLAB (функция mex должна быть видна в пути MATLAB) и он должен установить сродство процессора по вашему желанию.Вы даже можете передать маску сходства в качестве входных данных для функции, чтобы сделать ее более универсальной.

0 голосов
/ 18 июня 2014

Ниже приведена реализация функции 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 и его зависимыми библиотеками. Вот сообщение Раймонда Чена на эту тему.

...