SHOEISHA iD

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

CodeZine(コードジン) DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

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

基礎から学ぶOpenMP

OpenMPにおける変数の扱いと並列リダクション

基礎から学ぶOpenMP 第4回


ダウンロード サンプルコード (13.3 KB)

スレッドプライベート変数のコピー

 スレッドが持つプライベート変数を共有したくはないが、変数の値をコピーしたい状況があります。OpenMPではこの状況で使用できる指示句が2つ定義されています。それは、copyincopyprivateです。最初にcopyinを解説します。

 copyin指示句で指定できる変数は、スレッドプライベート変数だけです。copyin指示句を使用する場合、変数をスレッドプライベート変数に設定するthreadprivate指示句と併用します。

 copyin指示句の使用法をサンプルプロジェクトCopyInSampleのコードで示します。

copyin指示句の扱い方を示すサンプル
#include <stdio.h>
#include <omp.h>

/* グローバル変数をスレッドプライベート変数にする */
int x;
#pragma omp threadprivate( x )

int main()
{
    /* 静的変数をスレッドプライベート変数にする */
    static int y;
    #pragma omp threadprivate( y )

    /* 変数を初期化 */
    x = 0;
    y = 0;

    #pragma omp parallel copyin( x, y )
    {
        /* スレッドプライベート変数の初期値を表示 */
        printf( "スレッド:%d\t Xの値 = %d, Yの値 = %d\n", omp_get_thread_num(), x, y );

        /* 以下のプログラムは他のスレッドに影響を与えないが、ブロック外に影響を与える。 */
        x = 10;
        y = 20;
    }

    /* 最終値を表示 */
    printf( "【最終値】\t Xの値 = %d, Yの値 = %d\n\n", x, y );
    return 0;
}

 copyin指示句を使用すると、初期値をコピーすることができます。繰り返しになりますが、copyin指示句は、スレッドプライベート変数のみ使用できます。また、静的変数もしくはグローバル変数でなくてはなりません。これは一見不自由な制限ですが、静的変数とグローバル変数は、並列処理においてバグを生み出すきっかけになるので、コードを安全なものにする機能だと言えます。この制限により変数のスコープが狭くなり、並列処理で発生するバグが自然と少なくなります。

 次はcopyprivate指示句を解説します。copyprivate指示句を使用すると、あるスレッドの値をブロードキャストすることができます。文章では分かりにくいと思いますので、サンプルプロジェクトCopyPrivateSampleのコードを見てください。

copyprivate指示句の使い方を示すサンプル
#include <stdio.h>
#include <omp.h>

/* グローバル変数をスレッドプライベート変数にする */
int x;
#pragma omp threadprivate( x )

int main()
{
    /* 静的変数をスレッドプライベート変数にする */
    static int y;
    #pragma omp threadprivate( y )

    /* 変数を初期化 */
    x = 0;
    y = 0;

    #pragma omp parallel num_threads( 10 ) copyin( x, y )
    {
        /* 他のスレッドに存在するプライベート変数の値を変更 */
        #pragma omp single copyprivate( x, y )
        {
            x = 100;
            y = 200;
            printf( "スレッド%dが値を変更しました\t Xの値 = %d, Yの値 = %d\n", omp_get_thread_num(), x, y );
        }

        /* 現在の変数の値を表示 */
        x *= ( omp_get_thread_num() + 1 );
        y *= ( omp_get_thread_num() + 1 );
        printf( "スレッド:%d\t Xの値 = %d, Yの値 = %d\n", omp_get_thread_num(), x, y );
    }

    /* 最終値を表示 */
    printf( "【最終値】\t Xの値 = %d, Yの値 = %d\n\n", x, y );
    return 0;
}

 このコードを実行すると、copyprivate指示句で指定されたブロック内のコードが、他のスレッドにも反映されているのが確認できます。

 copyprivate指示句は、single構文でのみ指定でき、ブロードキャストされるタイミングに注意せねばならないので、使用するべき状況が限られています。使用する際には十分に注意してください。

 これで、スレッドプライベート変数のコピーについての解説は終わりです。次項では、並列リダクションについて解説します。

次のページ
並列リダクション

修正履歴

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

基礎から学ぶOpenMP連載記事一覧

もっと読む

この記事の著者

インドリ(インドリ)

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

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

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

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/5290 2010/08/04 07:42

イベント

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

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

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

メールバックナンバー