OpenMPとクリティカルセクション

 atomic構文は、単一の単純なプログラムのみ適用できます。しかし、関係がある複数のプログラムを、不可分に処理したい場合があります。不可分とは、複数のスレッドが、共有するリソースを同時に操作しない事です。
 並列プログラミングでは、共有リソースは不可分に処理しないと、正常な結果を得られません。この場合は、クリティカルセクションを使用します。OpenMPを使って、クリティカルセクションを実現したい場合、critical構文(#pragma omp critical)を使用します。
 文章だけでは分かりにくいと思いますので、サンプル(C言語使用)を元に解説を続けます。
#include <stdio.h>

int main()
{
    int i, x, y, max;
    max = 10000;

    /* クリティカルセクションなしで計算 */
    x = y = 0;
    #pragma omp parallel for shared( x, y )
    for ( i = 0; i < max; i++ ) {
        ++x;
        y += x;
    }
    printf( "critical構文を、指定していない場合の値は[x:%d][y:%d]です。\n", x, y );

    /* クリティカルセクション内で計算 */
    x = y = 0;
    #pragma omp parallel for shared( x, y )
    for ( i = 0; i < max; i++ ) {
        #pragma omp critical
        {
            ++x;
            y += x;
        }
    }
    printf( "critical構文を、指定した場合の値は[x:%d][y:%d]です。\n\n", x, y );
    return 0;
}

 このサンプルは、共有変数xとyの値を計算しています。変数xとyは、互いに関係が深いと仮定して下さい。サンプルを実行すれば、critical構文を使用しないと、更新の喪失が起こる事が確認できます。
 atomic構文を複数使えばいいと思う方もいるでしょうが、変数xとyの関係が深い場合、それぞれの変数がアトミックに更新されても、処理結果は予想外のものになり、正常な処理ではなくなる可能性があります
 何故ならば、並列処理では、同時に複数の処理が実行されますので、他のスレッドが処理した結果が混ざってしまう場合があるからです。処理A内で、処理Bが更新したyの値を使用してしまった場合、処理結果は予想もつかないものになるでしょう。まとまった処理は、クリティカルセクションで一度に指定しましょう。
 critical構文は#pragma omp critical( name )のように、クリティカルセクションに名前を付ける事が出来ます。名前を付ける事により、同時に実行できる処理を増やす事が出来ます。
例えば、#pragma omp critical( critical0 )と#pragma omp critical( critical1 )を指定したとします。この場合、名前を付けなかった時とは違い、クリティカルセクション0とクリティカルセクション1内のプログラムが同時に実行されます。一方、名前を付けなかった場合、未指定の名前(unspecified name)と看做され、同時に一つのクリティカルセクション内のプログラムしか処理する事が出来ません。
 ただし、複数のクリティカルセクションは、互いに関係がない処理に指定して下さい。関係がある処理に対して、複数のクリティカルセクションを使用すると、正常な処理結果を得られません。
 最後に、critical構文を使用するにあたって、一つ注意するべきことを述べます。critical構文を多用しないでください。クリティカルセクションは、共有リソースを単一スレッドのみ処理できるようにする技術なので、並列処理のパフォーマンスを下げます。本当に必要な時だけ使用するようにして下さい。


【参考資料】

テーマ : プログラミング
ジャンル : コンピュータ

コメントの投稿

非公開コメント

お久しぶりです

お久しぶりです。又コメントがヒートアップされていたようなので眺めておりました。

さて…
>atomic構文は、単一の単純なプログラムのみ適用できます
いいえ。
「単一の単純なプログラム」ではなく「後続の複合代入文を不可分的に実行」します。

>不可分とは、複数のスレッドが、共有するリソースを同時に操作しない事
いいえ。
不可分とはdo or not doです。
complete or nothingでも可でしょうか。
「共有するリソースを同時に操作しない事」は排他です。

>クリティカルセクションを実現したい場合
クリティカルセクションは排他が必要なエリアを指します。
排他制御を実現したい場合、が正しいでしょう。
クリティカルセクションとクリティカルリージョンを誤認されていませんか?

お一人で開発を長くされていると、
どうしても言葉の解釈や表現が独自ルールになってしまいますね。

インドリさんを指摘する方はどうも、
論拠を示さず楽しんで指摘する方が多いように見えましたので、
修正例もあわせ、コメントさせていただきました。

暑い日が続きますが、お体等壊されませんよう。

Re: お久しぶりです

> お久しぶりです。又コメントがヒートアップされていたようなので眺めておりました。
>
お久しぶりです。

> さて…
> >atomic構文は、単一の単純なプログラムのみ適用できます
> いいえ。
> 「単一の単純なプログラム」ではなく「後続の複合代入文を不可分的に実行」します。
>
正確さに拘るのであれば、残念ながらその表現も不正確です。
あくまでも正確さに拘るのであれば、OpenMPの仕様書を読むべきだと私は考えております。
また、深く追求するときりがありませんので、簡単な表現にとどめている次第です。
余りにも正確さに拘ると、仕様書と同じように読みにくくなりますし、前後の文章で「一見単純に見える命令文」と書いているのでこう表現しております。

> >不可分とは、複数のスレッドが、共有するリソースを同時に操作しない事
> いいえ。
> 不可分とはdo or not doです。
> complete or nothingでも可でしょうか。
> 「共有するリソースを同時に操作しない事」は排他です。
>
そうです排他制御の事を言っております。
この場面で排他制御というと、「同期処理とどう違うのか?」などと言った疑問がわくと思いましたので、敢えて排他制御とは言いませんでした。
また、排他制御を記述すると、OS理論も絡み非常に話しが長くなりますので、それを避ける意味合いもあります。
不可分の部分ですが、前の文を受けて、「どのような事をしたいのか」を表現しております。


> >クリティカルセクションを実現したい場合
> クリティカルセクションは排他が必要なエリアを指します。
> 排他制御を実現したい場合、が正しいでしょう。
> クリティカルセクションとクリティカルリージョンを誤認されていませんか?
残念ながらそれは不正確な表現です。
共有変数を参照/更新するソースコード部分をクリティカルセクションと呼びます。
また、その範囲を排他制御する仕組みもクリティカルセクションと呼ばれております。
クリティカルリージョンも同じ意味合いで使用され、著者が好みで選んでいるのが現状です。
この記事の場合、クリティカルリージョンの方を使用すると、読者が混乱する恐れがあります。
「何故、クリティカルセクション構文でクリティカルリージョンを扱うんだ?」

> お一人で開発を長くされていると、
> どうしても言葉の解釈や表現が独自ルールになってしまいますね。
>
いいえ。独りでシステムを構築できるだけであって、当然チーム開発も請け負っています。
独りでシステムを構築できるのですから、どの作業工程でも請け負っています。
独りで出来るからと言って、仕事の窓口を自分で狭める意味はありません。
それに、当然複数の専門書を参考にしております。
こういった記事は、正確に書くときりがない上に、相手に伝えるという目的が達成できませんので、情報量をコントロールしております。
エンドユーザーや、管理職の方を話しをする時、正確さに拘ると趣旨が伝わりません。
また、誰かに教える時も同様で、情報量をコントロールしないと、「基礎を教える」という目的を達成できません。
これは、コンサルティング業務や、集団開発で身に付いたテクニックの一種です。
どうやら、貴方様は何らかの先入観を持っておられるようなので言っておきます。
誹謗中傷集団は、知識と語彙が少なく、理解できない専門用語を全て「インドリ独自の言葉」と吹聴しているだけです。
彼らは理解できない事や、違う意見を言う人全てをインドリと呼ぶ、一種の病気に罹っています。

> インドリさんを指摘する方はどうも、
> 論拠を示さず楽しんで指摘する方が多いように見えましたので、
> 修正例もあわせ、コメントさせていただきました。
>
> 暑い日が続きますが、お体等壊されませんよう。
記事の目的とは違っているだけであって、貴方の言う事は特に間違っていないので、気にしないでください。
ごきげんよう。

かの宗教組織には困ったものだ

誹謗中傷集団が妄想を吹聴し、他者に先入観を埋め込んでいるので困っております。
誹謗中傷集団は、自分たちと違う意見を言う人は「インドリ」、分からない専門用語は全て「インドリが言っている」との妄想に取りつかれております。
その妄想を世間に広めるものですから、非常にたちが悪い。
これは明らかに名誉棄損です。
犯罪を行う事を目的とするあの教団には困ったものです。
賢明なる皆様は、妄想で動いている教団の言う事は真に受けないでください。

承認待ちコメント

このコメントは管理者の承認待ちです

承認待ちコメント

このコメントは管理者の承認待ちです

承認待ちコメント

このコメントは管理者の承認待ちです
プロフィール

Author:インドリ
みなさん、はじめまして、
コンニチハ。

ボクは、無限の夢(infinity dream)を持つネタ好きな虹色の鳥インドリ(in dre)です。
色々な情報処理技術を啄ばむから楽しみにしてね。

http://twitter.com/indori
は別人による嫌がらせ行為です。
私とは関係ないので注意して下さい。
次はなりすましブログなどをするかもしれませんが、ここ以外でブログをするつもりがないので、ここ以外にインドリのブログがあったとしても無視してください。


何度言っても分からない人が多いので、ここにコメント欄へ書き込むときの注意事項を書きます。


一、社会人としてのマナーをわきまえましょう。
一、妄想に基づく書き込みを止めてください。
一、暴言の類は書かないで下さい。
一、某誹謗中傷サイトの書き込みは彼らの妄想に基づく書き込みですから無視して、ここへ書き込まないで下さい。
一、コメント書く前に他のコメントよく読んでから行って下さい。
一、その他常識的に考えて迷惑なコメントはしないで下さい。


以上のルールを守れない人のコメントは削除します。



利用上の注意
ここに紹介してある文章およびプログラムコードは正確であるように心がけておりますが、内容を保証するものではありません。当サイトの内容によって生じた損害については、一切の責任を負いませんので御了承ください。


執筆したCodeZineの記事


【VB.NETで仮想CPUを作ろう】

  1. VB.NETで仮想CPUを作ろう
  2. レジスタの実装
  3. 仮想CPUのGUI化
  4. テストドライバの改良
  5. CPUの基礎動作の実装
  6. MOV命令の実装
  7. ADD命令実装
  8. SUB命令実装
  9. INC命令&DEC命令の実装と命令長
  10. MLU命令の実装とModR/Mについて
  11. DIV命令の実装とイベント設計について
  12. 機械語駆動式 関数電卓を作ろう!
  13. 機械語駆動式 関数電卓を作ろう! 解答編(前半)
  14. 機械語駆動式 関数電卓を作ろう! 解答編(後半)


【仮想ネットワーク実装でTCP/IPを学ぼう】
  1. TCP/IPの基礎と勘所
  2. ネットワークアクセス層の勘所
  3. インターネット層の勘所
  4. トランスポート層の勘所
  5. アプリケーション層の勘所
  6. セキュリティの基礎と仮想ネットワークの仕様
  7. GDI+と独自プロトコルの定義



【並列化】
インテル Parallel Studioを使って並列化プログラミングを試してみた
並列プログラミングの効率的なデバッグを実現する「Parallel Inspector」


【TBBシリーズ】
  1. インテル スレッディング・ビルディング・ブロックの概要
  2. インテルTBBから学ぶループの並列化
  3. スレッドセーフとインテルTBBのコンテナ
  4. インテルTBBのスレッドクラス


【OpenMPシリーズ】
  1. OpenMPの基礎構文
  2. OpenMPの実行時ライブラリと並列ループ
  3. OpenMPのメモリモデルとfork- joinモデル

最近の記事
最近のコメント
月別アーカイブ
カテゴリ
Ada (9)
COBOL (5)
C (6)
C++ (10)
C# (36)
D (25)
Java (8)
Perl (1)
Ruby (14)
PHP (2)
Boo (2)
Cobra (2)
LISP (6)
F# (10)
HTML (0)
XHTML (0)
CSS (0)
XML (0)
XSLT (0)
Scala (1)
WPF (0)
WF (0)
WCF (0)
LINQ (4)
MONO (5)
Linux (0)
MySQL (0)
ブログ内検索
リンク
最近のトラックバック
RSSフィード
By FC2ブログ

今すぐブログを作ろう!

Powered By FC2ブログ

ブロとも申請フォーム

この人とブロともになる

QRコード
FC2カウンター