(1)並列処理のリソース競合 [ 並列処理の不具合と対策 ]

 

並列処理の不具合と対策について、ブログをはじめます

並列処理プログラミング経験の浅い私が、pthreadライブラリを使用して並列化を行い、その過程で発生するトラブルの情報を掲載します。

 

題材プログラムは、簡単な演算処理プログラム

 

昨年につづいて今年も小さなプログラムで試します。

 

10進整数を引数で受け、0から引数値までの整数を4バイトで加算します。

4バイトのint型、2バイトshort型、この2つのサイズで計算し、計算結果が同じであることを確認します。

short型の加算処理では4バイト数値として加算するために、上位と下位の2度加算し桁上り処理をします。

・さらに、short型の加算処理は、2つの関数を動作させて並列処理します。

  

まず、ベースとなる逐次処理のプログラムを作りました。 C言語です。 

2つの型による加算関数は以下の通りです(プログラム全体は末尾からダウンロード可能です)

 

2つの関数の加算結果が同じ時は以下のような動作結果になります(引数の値には100000を指定しています)。 プログラム名は、sample1_0.exe です。

 

並列処理

 

2バイト関数の並列化処理では、0から加算してゆく関数と、指定値から0に向かって加算してゆく関数の2関数を並列に動かします。ぶつかったところで加算処理を停止します。

 

2つの加算関数は以下の通りです。

 

 

この2関数を並列動作させましたが、正しい加算結果を得られません。

 

 

誤動作の原因は変数の競合

  

並列処理では2つの関数が同時に動作するので、自分の処理を別の処理邪魔します

両関数が同じ変数をアクセスするために、個々の関数の想定外の値を使ってしまうのです。

 

 

何が起きているのか

  

2つの関数が同時に動作する際のいくつかの状況を考えてみます。

0x111111111 A関数 0x22222222 を加算し、 B関数 0x33333333 を加算する2つの処理例を以下に示します。

 

この場合、どちらも問題ありません。

さらに処理順序を細分化してみます。

 

 

この例でも問題ありませんが、もし矢印の部分の順序が逆転すると正しい結果が得られません

 

 

競合を回避するための排他処理

  

他の処理に邪魔されないようにするには、邪魔されたくない区間を単独で動作するようにします。

 

・指定区間では他関数の動作を排除する

・動作するには優先権が必要(優先権が得られない時は待つ)

 

 

競合を回避するための排他処理

  

他の処理に邪魔されないようにするには、邪魔されたくない区間を単独で動作するようにします。

  

・指定区間では他関数の動作を排除する

・動作するには優先権が必要(優先権が得られない時は待つ)

 

 

排他処理対策の結果は

 

排他処理を施して動作させたプログラムは、何時間待っても終わらなくなってしまいました。

次回は、この問題の調査と対策を行います。

 

 

ダウンロード
使用したプログラムソース(コンパイル方法はソースコメントを参照のこと)
1. sample1_0.c (逐次処理プログラムソース)
2. sample1_1.c (並列処理プログラムソース、ただし排他処理が無いので誤動作する)
3. sample1_2.c (並列処理プログラムソース、排他処理入りだがプログラムが終了しない)
Source_1.zip
zip ( 圧縮 ) ファイル 3.7 KB