プログラミングのヒント
プログラム開発のガイドライン
Parallel Computing Toolbox™ ソフトウェアのコードを記述する際は、複雑なアプリケーションに対し 1 ステップずつ進んでいく必要があります。各ステップでプログラムを検証することで、問題の可能性がある複数の点を同時にデバッグせずに済むようになります。過程中いずれかのステップで問題が生じた場合は、前のステップに戻り、コードを再確認します。
分散または並列計算アプリケーションで推奨されるプログラミング プラクティスは、以下のとおりです。
ローカル マシンで通常どおりコードを実行します。作業の進行に伴い関数と分散を同時にデバッグすることのないよう、まず、すべての関数を確認します。ローカル コンピューターにおいて、使用する関数を MATLAB® ソフトウェアの単一インスタンスで実行します。プログラミングのヒントについては、パフォーマンス向上の手法を参照してください。
独立ジョブと通信ジョブのいずれが必要かを判断します。アプリケーションに同時計算の実行が必要な大規模データセットがある場合は、分散配列を用いた通信ジョブが役立つ可能性があります。アプリケーションにループや繰り返しを伴う計算があり、各計算が互いに独立して実行できる場合は、独立ジョブが適している可能性があります。
分割できるようにコードを変更します。コードの分割方法を決定します。独立ジョブの場合は、タスクに分割する最善の方法を決定します。たとえば、for ループの反復ごとに 1 つのタスクを定義します。通信ジョブの場合は、並列処理を最大限に活用する方法を決定します。たとえば、大きな配列はすべてのワーカーに分散することができます。
spmd
を使用して並列機能を開発します。spmd
とローカル プールを使用して、複数のワーカーで並列に動作する関数を作成します。作業が進み、リモート クラスターでspmd
を使用する段階で、作業が完了する場合もあります。ローカル スケジューラで独立ジョブまたは通信ジョブを実行します。独立ジョブまたは通信ジョブを作成し、ローカル スケジューラを複数のローカル ワーカーと共に使用してそのジョブを実行します。これにより、コードがバッチ実行用に正しく作成されていることや、独立ジョブの場合に計算が適切にタスクに分割されることが確認されます。
ただ 1 つのクラスター ノードで独立ジョブを実行します。独立ジョブの 1 つのタスクのみを実行して、クライアントとクラスターの間のリモート分散が機能していることを確認し、追加のファイルとパスが正常に転送されることを確認します。
複数のクラスター ノードで独立ジョブまたは通信ジョブを実行します。独立ジョブに必要なすべてのタスクを、あるいは通信ジョブに必要なすべてのワーカーを含めるようにジョブを拡張します。
メモ
Parallel Computing Toolbox ソフトウェアを使用するには、MATLAB のクライアント セッションで Java® 仮想マシン (JVM™) を実行していなければなりません。MATLAB を起動するときに、-nojvm
フラグを使用しないでください。
MATLAB ワーカーの現在の作業ディレクトリ
MATLAB ワーカーのセッション開始時における現在のディレクトリは、次のとおりです。
CHECKPOINTBASE\HOSTNAME_WORKERNAME_mlworker_log\work
ここで、CHECKPOINTBASE
は mjs_def
ファイルに定義されており、HOSTNAME
はワーカーが実行されるノードの名前で、WORKERNAME
は MATLAB ワーカー セッションの名前です。
たとえば、ホスト nodeA52
で worker22
というワーカーが実行されており、その CHECKPOINTBASE
の値が C:\TEMP\MJS\Checkpoint
である場合、ワーカー セッションの開始時における現在のディレクトリは次のようになります。
C:\TEMP\mjs\Checkpoint\nodeA52_worker22_mlworker_log\work
ワーカーからのファイルへの書き込み
複数のワーカーが同一のファイルに書き込みを試みると、競合状態や衝突が発生したり、1 つのワーカーが別のワーカーのデータを上書きする可能性があります。これは以下の場合に発生の可能性が高くなります。
1 つのマシンにつき複数のワーカーがあり、それらが同じファイルに書き込もうとする。
ワーカーに共有ファイル システムがあり、同じパスを使用して書き込み対象のファイルを指定する。
エラーが表示される場合もありますが、エラーが発生せずに上書きが行われる場合もあります。問題を回避するには、各ワーカーまたは parfor
の反復が、データの書き込みや保存を行うファイルに単独でアクセスするようにしてください。複数のワーカーが同じファイルから読み取る場合は問題ありません。
オブジェクトの保存または送信
Parallel Computing Toolbox オブジェクトに対して関数 save
や load
を使用しないでください。こうしたオブジェクトに必要な情報の一部は MATLAB セッションの永続メモリに格納されており、ファイルには保存されません。
同様に、オブジェクトのプロパティを使用して並列計算プロセス間で並列計算オブジェクトを送信することはできません。たとえば、MATLAB ジョブ スケジューラ、ジョブ、タスクまたはワーカーのオブジェクトをジョブの JobData
プロパティの一部として MATLAB ワーカーに渡すことはできません。
また、MATLAB クライアントの Java 検索パスに読み込まれ、インポートされ、あるいは追加される System object (Java クラス、.NET クラス、共有ライブラリなど) は、ワーカーで明示的に読み込まれ、インポートされ、追加されない限り、ワーカーでは利用できません。タスク関数のコード以外にこれらのオブジェクトを読み込む一般的な方法として、taskStartup
や jobStartup
の使用が考えられます。また、並列プールのワーカーの場合は、poolStartup
や pctRunOnAll
も使用できます。
clear functions の使用
次を実行します。
clear functions
これにより、現在の MATLAB セッションからすべての Parallel Computing Toolbox オブジェクトが消去されます。オブジェクトは MATLAB ジョブ スケジューラに引き続き残ります。これらのオブジェクトをクライアント セッションで再作成する方法は、オブジェクトの復元を参照してください。
Simulink ソフトウェアを呼び出すタスクの実行
Simulink® ソフトウェアを使用するワーカー セッションでは、開始時に Simulink が自動で起動しないため、ワーカー セッションでの最初のタスクの実行に長時間かかる場合があります。Simulink は起動時ではなく、最初に呼び出されたときに起動します。タスク間でワーカーが再起動されない限り、このワーカー セッションの後続のタスクはより速く実行されるようになります。
関数 pause の使用
Macintosh または UNIX® のオペレーティング システムで実行されるワーカー セッションでは、pause(Inf)
は停止を実行せずにすぐに返されます。これは、割り込みができない場合にワーカー セッションがハングアップしないようにするためです。
大量データの送信
ネットワーク経由による多数のオブジェクトや大量のデータの送信を伴う操作には、長時間を要する場合があります。たとえば、ジョブに多数のタスクが含まれている場合に、ジョブの Tasks
プロパティやジョブの全タスクの結果を取得するには、長時間かかる可能性があります。添付ファイルのサイズ制限も参照してください。
ジョブの割り込み
ジョブとタスクはクライアント セッション外で実行されるため、クライアント セッションで Ctrl + C (^C) を使用してジョブとタスクに割り込むことはできません。ジョブやタスクの実行の制御または割り込みを行うには、cancel
、delete
、demote
、promote
、pause
、resume
などの関数を使用します。
ジョブの高速化
デスクトップ コンピューターでのコード実行よりも複数のワーカーでの実行の方が低速となることがあります。これは、タスクのスタートアップと終了の時間がタスク実行時間に比してかなり大きいときに起こる場合があります。この点で最も犯しやすい間違いは、タスクを非常に小さくする、つまりきめ細かく分けることです。もう 1 つの犯しやすい間違いは、各タスクで大量の入力データや出力データを送信することです。どちらの場合も、データの転送とタスクの初期化にかかる時間が、ワーカーが実際にタスク関数の評価に要する時間よりはるかに大きくなります。