ロック戦略が待ち時間に及ぼす影響

mttest のパフォーマンスデータが収集され、mttest.1.ermttest.2.er の 2 つの実験がパフォーマンスアナライザの別々のインスタンスで開かれていることを確認してください。 これらの作業がまだ済んでいない場合には、mttest サンプルのデータ収集を参照して実施してください。

ここでは、データに対する大域ロックと局所ロックがプログラムのパフォーマンスに及ぼす影響を示します。

  1. 4 CPU 実験 mttest.1.er の「関数」タブで、lock_local()lock_global() を検索します。

    この 2 つの関数の包括ユーザー CPU 時間は、ほぼ同じです。 これは、この 2 つの関数が同量の仕事を行っていることを意味します。 ところが、lock_global() の同期待ち時間は長く、lock_local() にはありません。

    2 つの関数の注釈付きソースコードを見れば、その理由がわかります。

  2. lock_global() をクリックし、「ソース」タブをクリックします。

    lock_global() は、大域ロックを使用して全データを保護します。 この大域ロックのため、実行中のスレッドすべてがデータにアクセスしようと競合します。一度にデータにアクセスできるスレッドは、1 個だけです。 その他のスレッドは、作業中のスレッドがロックを解放するまで、データへのアクセスを待たなければなりません。 このソースコード行が、同期待ち時間をもたらしています。

  3. 「関数」タブで lock_local() をクリックし、「ソース」タブをクリックします。

    lock_local() は、特定のスレッドの作業ブロックにあるデータだけをロックします。 いかなるスレッドも他のスレッドの作業ブロックにはアクセスできないので、競合したり同期待ちのために時間を浪費したりすることなく、各スレッドが処理を進められます。 このソースコード行、つまり lock_local() の同期待ち時間は、ゼロです。

  4. 1 CPU 実験 mttest.2.er のメトリックセレクションを次のように変更します。
    1. 「表示」and choose「データ表示方法の設定」を選択します。
    2. 「排他的ユーザー CPU 時間」と「包括的 Sync 待ち時間」を選択解除します。
    3. 「時間」欄で「包括的全 LWP 時間」、「包括的 CPU 待ち時間」、「包括的他の待ち時間」を選択します。
    4. 「適用」をクリックします。
  5. 1 CPU 実験の「関数」タブで、lock_local()lock_global() を検索します。

    4 CPU 実験の場合と同じように両方の関数の包括ユーザー CPU 時間は同じなので、同量の仕事を行っていることになります。 同期動作も 4 CPU システムの場合と同じであり、lock_global() は長時間を同期待ちに費やしますが、lock_local() は費やしません。

    ただし、lock_global() の LWP 総時間は、lock_local() より小さい値です。 これには、各ロッキング方式が CPU 上でのスレッドの実行をスケジューリングする方法が起因しています。 lock_global() が設定する大域ロックでは、各スレッドが最後まで逐次実行できます。 lock_local() が設定する局所ロックでは、各スレッドの実行の一部を CPU 上で行うようにスケジューリングされ、すべてのスレッドが実行を完了するまでこのプロセスが繰り返されます。 いずれの場合も、スレッドはかなりの時間を作業待ちに費やします。 lock_global() のスレッドは、ロックを待ちます。 この待ち時間は、「包括的 Sync 待ち時間」メトリックと「その他の待ち時間」メトリックに表示されます。 lock_local() のスレッドは、CPU を待ちます。 この待ち時間は、「待ち CPU 時間」メトリックに現われます。

  6. 1 CPU 実験 mttest.2.er のメトリック選択を次のようにデフォルト値に戻します。

    まだ開いたままの状態であるはずの「データ表示方法の設定」ダイアログで、以下の操作を行います。

    1. 「排他的ユーザー CPU 時間」と「包括的 Sync 待ち時間」を選択します。
    2. 「時間」欄で「包括的全 LWP 時間」、「包括的 CPU 待ち時間」、「包括的他の待ち時間」を選択解除します。
    3. 「了解」をクリックします。


著作権と商標について