このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。
プラント モデルのマルチコア展開
この例では、グラフィカルな分割を使用することで、マルチコア プロセッサ上でマルチスレッド コードの実行を利用する方法を示します。この例では、マルチスレッド コードを生成するために Simulink® Coder™ が必要です。
概要
モデルベース デザインの 1 つの目的は物理システムの現実的なモデルを作成し、これらのモデルをリアルタイムでシミュレーションすることです。これにより、たとえばハードウェアインザループ (HIL) を使用してコントローラーを検証することができます。しかし、多くの機能がプラント モデルに追加されているため、計算要件がシングルコア処理システムによって利用可能なリソースを超えてしまう可能性があります。
プラントとコントローラーを別個に分割することは、複雑なモデルの計算要件に対応する 1 つの方法です。Simulink® では、Model ブロックを使用してプラントを分割し、次に、各サブモデルによって生成されたコードをスレッドに割り当てて、Simulink Real-Time™ などの HIL システム上でのリアルタイム実行を実現します。この仕組みを確認するために、リアルタイム実行環境の代わりにホスト コンピューターを使用し、次のモデルのリアルタイム マルチスレッド コードを生成してみましょう。
slexMulticoreSolverExample
対称マルチコア処理
上の図は、モデル用に生成されたコードが 2 つのスレッドに分かれていることを示しています。この例では、ターゲットが対称マルチコア プロセッサであると仮定されているため、スレッドは特定のコアに関連付けられていません。オペレーティング システムは、スレッド実行をスケジュールするときに、コアを最大限に利用する必要があります。理想的には、最大の柔軟性を実現するために、スレッドの数 (Nt) はコアの数 (Nc) よりも多くなければなりません。[Generate Code and Profile Report] ボタンをダブルクリックしてマルチスレッド コードを生成し、実行をプロファイリングし、その結果を可視化します。この可視化によって、実行の各タイム ステップでコアがどのように使用されたかを示すコア占有マップが表示されます。オペレーティング システム スケジューラによって最適とみなされたとおりに、スレッドがコア間を移動することを確認できます。このようなタイプのスケジューリングは、オペレーティング システムが他のプロセスも実行する必要がある場合に役立ちます。
スレッドの同期
Simulink® Coder™ は、2 つのスレッドを 2 つの異なるコアで同時に実行できるコードを生成します。つまり、 および の信号値を 2 つのスレッド間で同期させる必要があることになります。ここに示されているように、Simulink® はこの要件に対処する複数のオプションを提供します。
以下のスクリプトを使用して、確定的なモードの効果をシミュレーションして示し、Simulink® がどのように同期を処理するかを理解します。
参照ソリューション (ode3) - Simulink® は、各メジャー タイム ステップおよびマイナー タイム ステップでデータを同期することで、参照ソリューションを提供するように構成されています。
ゼロ次ホールド - 各スレッドは、メジャー タイム ステップでのみデータを同期しながら、自身のソルバーを使用してそれぞれの方程式系を解決しています。
線形外挿 - ゼロ次ホールド モードに加えて、各ソルバーは線形予測を使用してデータを外挿し、データ レイテンシのエラーを補正します。
同期ポイントが滑らかな多くのシステムの場合、線形外挿モードは通信のボトルネックと数値精度の間で適切なトレードオフを提供します。
h = figure; hVal = ishold; hold on; mdl = 'slexMulticoreSolverExample'; dt = get_param(mdl, 'DataTransfer'); modes = { ... 'Ensure deterministic transfer (minimum delay)', ... 'None', 'k:', ... 'Ensure deterministic transfer (maximum delay)', ... 'Zero Order Hold', 'm', ... 'Ensure deterministic transfer (maximum delay)', ... 'Linear', 'b' ... }; for i=1:3:length(modes) dt.DefaultTransitionBetweenContTasks = modes{i}; dt.DefaultExtrapolationMethodBetweenContTasks = modes{i+1}; out = sim(mdl); plot(out.logsout.get('x1').Values.Time, ... out.logsout.get('x1').Values.Data, ... modes{i+2}); end legend('Reference solution (ode3)', ... 'Zero Order Hold Extrapolation', ... 'Linear Extrapolation');
モデルを閉じる
close_system('slexMulticoreSolverExample',0); close_system('slexMulticoreSolverMdlref',0); if ~hVal, hold off; end delete(h);