7

私はc++でアプリケーションを開発しています。アプリケーションのコンポーネントの 1 つは、データ処理に (Matlab エンジンを介して) Matlab を使用します。同時に、データ取得システムがデータをディスクにストリーミングしています。ときどき、集中的な Matlab 処理の期間中に、取得システムがクラッシュします。Matlab のプロセッサ アフィニティを使用可能なプロセッサのサブセットに設定することで、この問題は解決されます。ただし、アプリケーションは 1 日に数回、複数のマシンで起動されるため、毎回アフィニティを手動で設定するのは不便です。エンジンはショートカット経由ではなくアプリケーション内から起動されるため、ショートカットのコマンドライン経由でプロセッサ アフィニティを設定するトリックは機能しません。プログラムでアフィニティを設定する方法を探していましたが、成功は限られていました。

私は次のオプションを検討しました(優先順にランク付けされています):

  1. エンジンの起動時に、アプリケーション内から matlab エンジンのプロセッサ アフィニティを指定します。
  2. 完全な Matlab アプリケーション自体とは別に、matlab エンジンの既定のプロセッサ アフィニティを指定します。
  3. 最後の手段として、Matlab の既定のアフィニティを設定します (エンジンと非エンジンの両方の使用)。Matlab は展開マシンで他の目的に使用されるため、これは最も望ましくありません。他の用途に制限しないことが望ましいでしょう。

アプリケーション内からプロセッサ アフィニティを設定することは可能ですか。そうでない場合、この問題に取り組む正しい方法は何ですか? これらのオプションに関するアドバイス、またはその他の提案/解決策は大歓迎です。

4

3 に答える 3

6

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に直接移植できる場合があります。

于 2012-03-20T14:29:40.620 に答える
4

私はこの解決策を試していませんが、うまくいくようです。以下を実行する単純な mex 関数を作成します。

  1. GetCurrentProcessMATLAB プロセスへのハンドルを取得するための呼び出し
  2. を使用して、このプロセスに適切なアフィニティ マスクを設定します。SetProcessAffinityMask

ここで、アプリケーションが起動したら、通常の MATLAB 関数と同じようにこの mex 関数を呼び出すだけで (mex 関数は MATLAB パス上で可視でなければなりません)、必要に応じてプロセッサ アフィニティを設定する必要があります。関数への入力としてアフィニティ マスクを渡して、汎用性を高めることもできます。

于 2012-03-19T21:58:31.553 に答える
0

以下は、@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 関数を呼び出して、8 つの論理プロセッサすべてで MATLAB を実行できるようにします。

>> getenv('NUMBER_OF_PROCESSORS')
ans =
8

>> mex -largeArrayDims set_affinity.c
>> set_affinity(8)

半分の数のプロセッサーのみを使用するには、次のようにします。

>> set_affinity(4)

MSDN doc ページの次のコメントに注意してください。

プロセス アフィニティは、子プロセスまたは新しくインスタンス化されたローカル プロセスに継承されます。

SetProcessAffinityMask自分以外のプロセスから呼び出される可能性のある DLL を呼び出さないでください。

したがって、アフィニティをいじると、MATLAB とその依存ライブラリによって開始されるすべての計算に影響します。このトピックに関するRaymond Chen の投稿を次に示します。

于 2014-06-18T16:15:03.077 に答える