SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

基礎から学ぶOpenMP

OpenMPの基礎構文

基礎から学ぶOpenMP 第1回


  • X ポスト
  • このエントリーをはてなブックマークに追加

スレッド数のコントロールについて

 スレッド数をコントロールするには、実行時ライブラリと呼ばれるOpenMPで規定されている関数を使用します。

スレッド数の操作をするプログラム
#include <stdio.h>
#include <omp.h>

int main()
{
    int threadCount = 4; /*スレッド数*/

    //初期状態を表示
    printf( "初期状態の動的調節機能は%s\n\n", omp_get_dynamic() == 0 ?  "無効" : "有効" );

    /*スレッドの動的調節を有効にする*/
    omp_set_dynamic( 1 );
    printf ( "動的調節機能を有効化しました\n" );
    omp_set_num_threads( threadCount );
    #pragma omp parallel
    {
        printf ( "現在のスレッド数は%dです。\n", omp_get_num_threads());
    }
    printf( "現在動的調節機能は%s\n\n", omp_get_dynamic() == 0 ?  "無効" : "有効" );

    /*スレッド数を指定して並列実行*/
    omp_set_dynamic( 0 );
    omp_set_num_threads( threadCount );
    printf ( "動的調節機能を無効化しました。指定したスレッド数は%dです。\n", threadCount );
    #pragma omp parallel
    {
        printf ( "現在のスレッド数は%dです。\n", omp_get_num_threads());
    }
    printf( "現在動的調節機能は%s\n\n", omp_get_dynamic() == 0 ?  "無効" : "有効" );

    //終了
    printf( "\n\n" );
    return 0;
}
実行結果
実行結果

 このサンプルプログラムは、4つの実行時ライブラリomp_get_dynamic()omp_set_dynamicomp_get_num_threadsomp_set_num_threadsを使用しています。

 omp_get_dynamic()omp_set_dynamicは、スレッド数の動的調整が有効か無効かを決定するdyn-var内部制御変数の値を取得/設定するための関数です。動的調節が有効な時は、CPUのコア数に応じて処理が並列化されます。

 OpenMPでは、サポートするコンパイラが、あたかも変数をもつかのように振る舞うことになっております。これを内部制御変数と呼びます。omp_get_dynamic()omp_set_dynamicは、この変数を操作してスレッド数が動的に調節できるか否かを制御します。スレッド数の動的調節が有効な場合はdyn-varが0以外、無効な場合は0と定義されております。自動調節が可能なコンパイラのdyn-var内部制御変数の初期値は未定義ですので、このサンプルグラムに示したように確認や明示的に指定した方がよいでしょう。コンパイラによっては、omp_set_dynamic( 1 )を初めに指定しなくても自動調節が有効ですが、この2つの関数を明示的に使用しなければ、特定のコンパイラに依存するプログラムになってしまいます。

 omp_get_num_threadsomp_set_num_threadsは、スレッド数を指定するための関数です。omp_get_num_threadsをparallel構文の中で使用するとスレッド数が取得できます。parallel構文の範囲以外では必ず1を返しますので注意が必要です。そしてomp_set_num_threadsは、指定した数のスレッドをparallel構文内で生成するための関数です。もし指定した数のスレッド数が生成できなければどうなるかは未定義ですので、あまり大きな数は指定しない方がよいでしょう。

 この逆に、複数のスレッドで実行したくない処理が含まれている場合は、次のようにします。

paralell構文内で単一スレッドで処理する方法
#include <stdio.h>
#include <omp.h>

int main()
{
    #pragma omp parallel
    {
        printf ( "複数回表示\n" );
        #pragma omp single
        {
            printf("1回だけ表示\n");
        }
        printf ( "複数回表示\n" );
    }

    //終了
    printf( "\n\n" );
    return 0;
}

 このサンプルプログラムの様に、並列処理をしたい範囲内の一部のコードだけ逐次的に処理をしたい場合は、single構文を使用します。以上がスレッド数を変化させる基本的な方法です。

 他の方法として環境変数を使用するやり方があります。環境変数としてOMP_DYNAMICと、OMP_NUM_THREADSを設定することにより同様のことを行えます。

 環境変数を試すにはコマンドプロンプトを使用するとよいでしょう。まずcdコマンドでサンプルプログラムの実行ファイルがある場所へ移動します。次に2つのコマンドset OMP_NUM_THREADS=4set OMP_DYNAMIC=FALSEを実行して下さい。そして最後に実行ファイルの名前を指定してEnterキーを押すと、最初のサンプルの場合は4回「Hello, OpenMP!」と表示されます。

 以上でスレッドを操作する方法の説明は終わりです。

まとめ

 今回は初回ですので、OpenMPのもっとも基本的な知識について丁寧に解説しました。次回はさらに他のOpenMPの要素について丁寧に解説していきます。この記事がきっかけに並列処理について学習する方がおられれば望外の幸せです。

参考資料

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
基礎から学ぶOpenMP連載記事一覧

もっと読む

この記事の著者

インドリ(インドリ)

分析・設計・実装なんでもありのフリーエンジニア。ブログ「無差別に技術をついばむ鳥(http://indori.blog32.fc2.com/)」の作者です。アドバイザーをしたり、システム開発したり、情報処理技術を研究したりと色々しています。座右の銘は温故知新で、新旧関係なく必要だと考えたものは全て学...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/4693 2010/04/27 12:08

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング