インドリ [著] 2010/07/21 14:00

サンプルファイル 13.65 KB
← 1 2 3 4 →

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

 スレッドが持つプライベート変数を共有したくはないが、変数の値をコピーしたい状況があります。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構文でのみ指定でき、ブロードキャストされるタイミングに注意せねばならないので、使用するべき状況が限られています。使用する際には十分に注意してください。

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


<-
1 2 3 4
→
INDEX
OpenMPにおける変数の扱いと並列リダクション
はじめに
対象読者
必要な環境
並列処理と変数
変数の局所化
Page3
スレッドプライベート変数のコピー
並列リダクション
まとめ
参考資料
プロフィール
インドリ インドリ

分析・設計・実装なんでもありのフリーエンジニア。
ブログ「無差別に技術をついばむ鳥(http://indori.blog32.fc2.com/)」の作者です。

アドバイザーをしたり、システム開発したり、情報処理技術を研究したりと色々しています。

座右の銘は温故知新で、新旧関係なく必要だと考えたものは全て学習しています。

 


注目の求人情報
コンサルタント/グローバルファーム
ITコンサルティング、システムエンジニアリング(SE)
システムエンジニア/イントラネット開発
各種案件におけるDB2、Oracleなどのデータベース設計、構築、チューニング等を担当していただきます。 ...
プログラマ/メディア系IT企業
某人気サイトを支えるプログラマ部門のマネージャーの募集です! ▼業務内容 ・ポイントサイトのプ...

(最新日付順)

本記事は現在、新規コメントの受付を中止しております。ご了承ください。

スポンサーサイト

この記事のトラックバックURL: