はじめに
『ぽき』です。
早いもので入社してから半年経ちました。
振り返ってみると、大学時代は C 言語を扱っていたので、
HDL 言語の並列処理の考え方を理解するのには苦労しました。
今回はそんな逐次処理と並列処理について考えたいと思います!
逐次処理
逐次処理は 1 つずつ順番に処理する方法です。
次のような例が逐次処理です。
初期値は A = 0 , B = 0 , C = 0 で
1. A = A + 1
2. B = B + 2
3. C = A + B
1. → 2. → 3. と順番に計算します!
ではやってみましょう!
図 1 : 逐次処理のフローチャート
最初の条件として A = B = C = 0 です。
処理 1 、 1. で A の値が 1 増えます。( A = 1 , B = 0 , C = 0 )
処理 2 、 2. で B の値が 2 増えます。( A = 1 , B = 2 , C = 0 )
処理 3 、 3. で C に A と B を足した値が代入されます。( A = 1 , B = 2 , C = 3 )
1. , 2. , 3. と 3 つ命令があるので 3 回処理を行いました。
並列処理ではどうでしょう?
並列処理
初期値は A = 0 , B = 0 , C = 0
1. A = A + 1
2. B = B + 2
3. C = A + B
先ほどと同様に C の値を求めます。
並列処理では 1 回の処理で 1. , 2. , 3. が同時に計算されます。
つまり処理 1 で
1. A の値が 1 増える
2. B の値が 2 増える
3. C に A と B を足した値が代入される、
の 3 つが行われるということです。
さてここで突然ですが問題です。
この処理が 1 回終わった時の A , B , C の値はそれぞれいくつでしょう?
答えは A = 1 , B = 2 , C = 0 です!
いや、 C = 3 でしょう?
これを私は理解できず苦労しました。
なぜ C = 3 にならないのかを見てみましょう。
逐次処理と並列処理の違い
先ほどの図 1 は逐次処理の計算の流れを表しています。
上から 1 つ 1 つ処理しているので処理を行った後の値が分かり易いと思います。
では次に図 1 のように、並列処理で行う際の計算の流れを図 2 に示します。
図 2 : 並列処理のフローチャート
図 2 は逐次処理時と同じように処理を 3 回行った時のフローチャートです。
並列処理では処理 1 の段階、つまり A = 0 , B = 0 , C = 0 の状態で
C = A + B を計算するために C = 0 となります。
続けて処理 2 を行うと、C = 3 となるのですが、
A とB はそれぞれ A = 2 , B = 4 となっています。
さらに逐次処理と同じように処理 3 を行うと
A = 3 , B = 6 , C = 6 となり、先ほどの逐次処理の結果とすべての値が違ってきます。
1. , 2. , 3. の処理を同時に行うということは、
足並みを揃えてすべての処理を行うということなのです!
同じ計算を行っているにもかかわらず先ほどの逐次処理とは考え方が全く異なっていますね!
この逐次処理と並列処理の流れが一緒になってしまい、先ほどの問題で C = 3 と答えてしまったわけです。
ちなみに Verilog で記述する場合では、ノンブロッキング代入は並列処理で、
ブロッキング代入は逐次処理として認識されます。
詳しくは先輩が記事にしていたのでこちらでご覧ください。
終わりに
入社当時は「逐次処理を何個も並列にしたもの」が並列処理と考えていました。
しかし C 言語のような逐次処理の考え方で並列処理を行おうとすると、
例のように値が全く違います。
今回は簡単な例でしたが、実際に扱う回路はもっと複雑です。
この違いを頭に入れて HDL 言語は記述しなければいけないと改めて感じました。
今日の POINT
逐次処理はひとつの処理を 1 つずつ順番に処理する方法
並列処理は複数の処理を同時に処理する方法