OpenMPプログラミング - 複数のソースコードの並列実行

いちごパック > OpenMPの解説 > OpenMPプログラミング - 複数のソースコードの並列実行

セクション

OpenMPでは#pragma omp parallelがあると同じソースコードが並列に実行されますが、 スレッドごとに別々のソースコードを実行したいこともあります。 OpenMPでは、別々のソースコードを実行するために、セクションと呼ばれる機能を提供しています。 この機能を使うと、セクションごとに別々のスレッドを割り当てて実行させることができ、 その動作は次の図のようになります。 この図のようにスレッドの数がセクションの数よりも多い場合は、何もしないスレッドができることもあります。
#pragma omp sectionsは、その対象範囲をセクションで区切り、 セクションごとに1つのスレッドで実行するよう指示します。 #pragma omp sectionsの直後から1つ目のセクションが開始します。
#pragma omp sectionはセクションの区切りを指示します。 この位置で現在のセクションが終了され、次のセクションが開始されます。
omp sectionsの動作がわかる例を示します。次の例は、omp sectionsだけを使っています。
#include <iostream>
#include <omp.h>

int main()
{
    #pragma omp parallel
    {
        #pragma omp sections
        {
            #pragma omp critical(crit_cout)
            {
                std::cout << "section: ichigothread "
                          << omp_get_thread_num() << std::endl;
            }
        }
        #pragma omp barrier
    }

    return 0;
}
このソースコードはomp sectionsの中にセクション区切りがありませんので、 セクションが1つしかありません。したがって1つのスレッドで実行され、その出力は次のようになります。
section: ichigothread 0
次の例のようにセクション区切りを入れると、セクションごとに並列に実行されるようになります。
#include <iostream>
#include <omp.h>

int main()
{
    #pragma omp parallel
    {
        #pragma omp sections
        {
            #pragma omp critical(crit_cout)
            {
                std::cout << "section 1: ichigothread "
                          << omp_get_thread_num() << std::endl;
            }
            #pragma omp section
            {
                #pragma omp critical(crit_cout)
                {
                    std::cout << "section 2: ichigothread "
                              << omp_get_thread_num() << std::endl;
                }
            }
            #pragma omp section
            {
                #pragma omp critical(crit_cout)
                {
                    std::cout << "section 3: ichigothread "
                              << omp_get_thread_num() << std::endl;
                }
            }
            #pragma omp section
            {
                #pragma omp critical(crit_cout)
                {
                    std::cout << "section 4: ichigothread "
                              << omp_get_thread_num() << std::endl;
                }
            }
        }
        #pragma omp barrier
    }

    return 0;
}
その結果の1例は次のようになります。
section: ichigothread 0
セクションを実行するスレッドは決まっていません。 この出力例からもわかるように、例えば4つのスレッドで4つのセクションを実行しようとしても、 1つのスレッドが2つ以上のセクションを実行することもあります。

関連ページ

  • OpenMPの解説 目次
  • 前の項目: for文の並列実行
  • 次の項目: 並列実行の競合対策