マルチスレッドの背景知識 -マルチスレッドプログラミング

いちごパック > OpenMPの解説 > マルチスレッドの背景知識 -マルチスレッドプログラミング

プログラミングモデル

マルチスレッド向けプログラムを書く方法は、 大きく分けると次の2種類あります。
方法プログラムコードの特徴
同じコードを使う同一のプログラムコードを使いまわします。同じ処理を複数のスレッドに分割する処理に向いている。
別のコードを使うスレッド単位で処理を書きます。処理単位でスレッドに分割する処理に向いています。
これらについて順に説明していきます。

複数のスレッドで同じコードを使う

スレッドごとにデータを分割し、各スレッドで同じコードを使います。 例えば1から100までを加算する処理であれば、 まず次のように、ある数から別のある数までを加算する関数を用意します。
int ichigo_sum(int numbegin,int numend)
{
  int ret = 0;
  for ( int ichigonum = numbegin; ichigonum <= numend; ichigonum++ )
    ret += ichigonum;
  return ret;
}
各スレッドでこの関数を呼び出せば、スレッド数によらず同じコードが使えます。 2スレッドの場合の疑似コードは次のようになります。
  int ichigoval_1, ichigoval_2, ichigoval;
  if (is_thread_1()) ichigoval_1 = ichigo_sum(1, 50);
  if (is_thread_2()) ichigoval_2 = ichigo_sum(51, 100);
  thread_barrier();
  if (is_thread_1()) ichigoval = ichigoval_1 + ichigoval_2;
疑似コードにおいて、 is_thread_1()はスレッド1、is_thread_2()はスレッド2の場合にtrueになる関数、 thread_barrier()はバリア関数です。 最初に各スレッドの結果をichigoval_1とichigoval_2に格納していますが、 この時点では別々の変数(メモリ)に結果に保存するため、同期は必要ありません。 次にスレッド1ではichigoval_1とichigoval_2を読み込むため、 この時点で同期が必要になります。
この疑似コードではバリアを使っていますが、クリティカルセクションでも同期は可能です。 クリティカルセクションを使う場合は、 スレッド間で共有されるichigoval_2に対してクリティカルセクションを用意します。

スレッドごとに別のコードを使う

スレッドごとに別々の処理を行わせたい場合は、別のコードを用意します。 例えば、1から100までを加算した結果と、 1から99までの数を10000から引いた結果を比較したい場合、 各処理を別々のスレッドで実行する疑似コードは次のようになります。
  int ichigoval_1, ichigoval_2, ichigoval;
  if (is_thread_1()) {
    ichigoval_1 = 0;
    for ( int ichigonum = 1; ichigonum <= 100; ichigonum++ )
      ichigoval_1 += ichigonum;
  }
  if (is_thread_2()) {
    ichigoval_2 = 10000;
    for ( int ichigonum = 99; ichigonum >= 1; ichigonum-- )
      ichigoval_2 -= ichigonum;
  }
  thread_barrier();
  if (is_thread_1()) {
    std::cout << "difference = " << ichigoval_1 - ichigoval_2 << std::endl;
    std::cout << "ichigoval_1 = " << ichigoval_1 << std::endl;
    std::cout << "ichigoval_2 = " << ichigoval_2 << std::endl;
  }
この方法を使うとスレッド単位で細かな処理を記述できますが、 コーディング量が多くなり、またスレッド数に応じて別のプログラムコードが必要になります。 複数のスレッドで同じコードが使えるのであれば、同じコードを使ったほうが良いでしょう。

関連ページ

  • OpenMPの解説 目次
  • 前の項目: プロセスとスレッド