ここでは、まず画像処理に限らず、処理一般における3つの並列性について説明する。一般に処理の並列性としては以下の3種類がある。
以下では、それぞれについて順に説明していく。
データ並列性とは、複数のデータに対して同時に同一の演算が行える性質のことを指す。例えば、横が100画素、縦が100画素の1枚の画像データに対して一律に定数Aを乗算する処理を考える。この場合、次の(1)と(2)とで処理結果は変わらない。
(1)1つの画素データに対して定数Aを乗じる命令を、1つずつ1万回実行する
(2)横方向の100個の画素データに対し、まとめて一律に定数Aを乗ずる命令を100回実行する
このように、複数のデータ(この例では横方向の100個の画素データ)をまとめて(並列に)、1度に同一の演算を施すことができる性質がデータ並列性である(図4)。
データ並列性がある場合、(2)のように複数のデータ(横方向100個のデータ)を1つのベクトルデータとし、それに対して一律の演算を実行したと考えることができる。そのため、(2)の演算をベクトル演算と呼ぶことがある。あるいは、1命令で複数のデータに対して演算を行うことから、SIMD(Single Instruction Multiple Data)演算とも呼ばれる。(2)の例では、データ並列性による並列度は100である。乗算器を100個横に並べて1命令で1度に100個の乗算を行うので、命令数は(1)と比べて1/100となる。
画像処理アプリケーションはデータ並列性を持つものが多い。また多くの場合、その並列度が高い。この種の代表的な処理としては、エッジ抽出、エッジ強調、低域通過フィルタなどの線形フィルタ群や、色空間変換などがある。
一方、データ並列性を持たない処理としては、1枚の画像の連結領域に対するラベリング処理などがある。連結領域のラベリング処理の場合、横方向/縦方向ともに画素データの依存性があるため、ベクトル処理は行えない。
命令並列性とは、複数の命令を同時に実行できる性質のことである。例として、図5に示した構成のプロセッサで、「処理の例」に示した3つの加算を処理するケースを考える。3つの加算のうち、図5のような構成のプロセッサでは、(C)と(D)の加算は同時に実行できる。この場合、(C)と(D)は命令並列性を持つと言う。それに対し、加算(G)は、(C)と(D)の結果を得てからでなければ実行できない。このように、(G)と(C)と(D)の3演算の組は命令並列性を持たない。ただし、命令並列性は名前のとおり、プロセッサがどのような命令セットを持つかによって決まるものである。そのため、プロセッサの構成によっては、(G)と(C)と(D)が命令並列性を持つことがある(詳細は後述)。このように、命令並列性は処理内容とプロセッサの命令セットのペアで考えなければならないので注意が必要だ。
命令並列性を実現する方式としては、同時実行する複数の命令を動的にハードウエアが選んで実行する方式と、コンパイラが静的に解析して選ぶ方式の2通りがある。前者はスーパースカラ型、後者はVLIW(Very Long Instruction Word)型と呼ばれている。
スーパースカラ型の利点は、ハードウエアを拡張する際にオブジェクトコード(バイナリとなった命令列)に互換性があることだ。これは、ユーザー(ソフトウエア開発者)にとっては非常に大きなメリットとなる。ただし、スーパースカラ型には、同時に実行できる命令を管理するための制御系回路の面積が大きくなるという欠点がある。
一方、VLIW型では、ハードウエアを拡張するとオブジェクトコードの互換性がなくなってしまう。すなわち、ソースコードを書き換えたり、再コンパイルしたりする必要が生じ、ユーザーにとってはソフトウエア資産の再利用性が下がることになる。ただし、VLIW型では同時実行命令を管理するハードウエアが不要なので、制御系回路の面積と消費電力は少なくて済む。そのため、コスト重視の組み込み用途では、VLIW型のプロセッサが多用される。
スレッド並列性とは、複数のプログラム、関数など、ある大きさの処理単位(スレッド)のレベルで同時に処理できる状態のことを言う。例として、フレーム中のブロックを入出力としてラスタスキャン順に進む、関数A、Bから成る処理を考える(図6)。この場合、入力フレーム中のブロックnに対する関数Aの処理と、中間フレーム中のブロックnに対する関数Bの処理は同時には実行できない。しかし、入力フレーム中のブロックn+1に対する関数Aの処理と中間フレーム中のブロックnに対する関数Bの処理であれば、同時に並列実行することができる。このような状況がスレッド並列性を持つ例である。
このように、スレッドはある程度の大きさの命令列とデータを持つ。そのため、スレッドとハードウエアの対応としては、1つのスレッドに対して1つのプロセッサコアを与えることが多い。すなわち、スレッドを並列処理する方式としては、マルチコアプロセッサを利用して複数のプロセッサコアを同時に動作させるという手法がとられる。マルチコアプロセッサでは、各コアで複数のデータが複数の命令によって処理されるため、MIMD(Multiple Instruction Multiple Data)処理の一形態であると考えることができる。マルチコアプロセッサでスレッド並列性を利用して効率良く処理を行う上でポイントとなるのは、スレッドの分割の仕方と各プロセッサコアへのスレッドの分配の仕方である。一連の処理をいくつかのスレッドに分割する作業は、現状ではコンパイラなどのツールではなく、手作業で行うことが多い。分割後のスレッドの各コアへの分配は、全体制御用のプロセッサが各スレッドの依存関係を分析した上で各プロセッサコアに割り当てることなどにより行われる。
Copyright © ITmedia, Inc. All Rights Reserved.