Set the affinity of the processor to the MATLAB engine (Windows 7)

I am developing an application in C ++. One of the components of the application uses Matlab (through the Matlab engine) to process data. At the same time, the data acquisition system transfers data streams to disk. Sometimes, during periods of heavy Matlab processing, the data collection system crashes. Having established the proximity of the Matlab processor to a subset of the available processors, this problem is resolved. However, since the application is launched several times a day, and on several machines it is inconvenient to manually configure affinity each time. The process of merging the processor using the shortcut command line does not work, since the engine is launched from my application, and not using the shortcut. I was looking for a way to programmatically establish affinity, but with limited success.

I reviewed the following options (ranked in order of preference):

  • Determine the affinity of the processor for the matlab engine from the application when the engine is running.
  • Determine the default processor compatibility for the matlab engine separately from the Matlab application itself.
  • As a last resort, set the default binding for Matlab (for both engine and non-motor use). This is least desirable since Matlab is used for other purposes on deployment machines, and it would be preferable not to limit it to other applications.

Is it possible to establish the affinity of the processor from my application, and if so, how? If not, what is the correct way to solve this problem? Any advice on these options or other suggestions / solutions would be welcome.

+7
source share
3 answers

You seem to be on Windows. You can directly call from .NET from Matlab to manipulate the processor merge mask and avoid creating a MEX file. The System.Diagnostics.Process class has processor affinity controls, as described in this solution . It uses the Matlab function, which uses it. First run it in the Matlab engine after it starts.

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)); 

Since Matlab provides objects of the standard .NET library on Windows, you can sometimes search for such questions in the C # or .NET section and pass the answer directly to Matlab.

+6
source

I have not tried this solution, but it looks like it should work. Create a simple mex function that does the following:

Now that your application starts, just call this mex function just like the regular MATLAB function (the mex function should be visible on the MATLAB path), and it should set the proximity of the processor as you wish. You can even pass an affinity mask as an input to a function to make it more universal.

+4
source

The following is the implementation of the MEX function described by @Praetorian (shows how to use the SetProcessAffinityMask function ):

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()); } } 

Example:

On my quad-core hyper-threading machine, I would call the MEX function as follows so that MATLAB could execute on all 8 logical processors:

 >> getenv('NUMBER_OF_PROCESSORS') ans = 8 >> mex -largeArrayDims set_affinity.c >> set_affinity(8) 

To use only half the number of processors:

 >> set_affinity(4) 

Note the following note in the MSDN document page :

A process affinity is inherited by any child process or a local process created.

Do not call SetProcessAffinityMask in a DLL that may be caused by processes other than your own.

Thus, communication with affinity will affect all calculations initiated by MATLAB and its dependent libraries. Here is Raymond Chen 's post on the topic.

0
source

All Articles