FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

Computer Architecture 6th Editionの7章"Domain-Specific Architecture" を読む (7.7章 Pixel Visual Core, パーソナルモバイル画像処理ユニット 続き)

Computer Architecture, Sixth Edition: A Quantitative Approach (The Morgan Kaufmann Series in Computer Architecture and Design)

Computer Architecture, Sixth Edition: A Quantitative Approach (The Morgan Kaufmann Series in Computer Architecture and Design)

7.7章は DSAの一つの例としてPixel Visual Coreを取り上げている。前回の続き。

あまりネット上で見たことのない情報が公開されているが、参考文献はどこなのだろうか? あるいは、David.A Patterson 先生はGoogleにも所属しているので、そこからの情報なのかな。 Pixel Visual Coreの内部情報が、かなり詳細に乗っている。

目次

これは著者が読んだ内容をまとめているだけなので、誤訳、理解不足により誤っている可能性があります!鵜呑みにしないようにお願いします。


7.7章 Pixel Visual Core, パーソナルモバイル画像処理ユニット

(続き)

Pixel Visual Coreのプロセッサ

16×16個のPEと1次元当たり4つのHaloによって、PEアレイもしくはベクトルアレイと呼ばれ、Pixel Visual Coreの主要な計算ユニットである。 シートジェネレータ(Sheet Generator: SHG)というロードストアユニットを持っている。 SHGは1×1から256×256ピクセルのブロックのメモリ中で参照することができる。

Pixel Visual Core内部は2コア以上のPEを含んでいるので、PE間はNOCで接続されている。 NOCは基本的に隣接PEとの接続する構成となっている。 このNOCは2次元メッシュ状に構成されている。

Pixel Visual Coreはスカラレーンというプロセッサも持っている。 このスカラレーンは、ベクトルアレイに普通のプロセッサのように、ジャンプ、分岐、割り込み、命令制御フローなどの処理を実行してはならない。 このスカラレーンは小さな命令メモリを持っており、これはスカラプロセッサのSIMD命令のフローに似ている。

さらに、Pixel Visual CoreはDMAエンジンを持っており、DRAMとラインバッファの転送を高速に実行することができる。

Pixel Visual Coreの命令セットアーキテクチャ

Pixel Visual Coreの命令セットはGPUのように2ステップのコンパイルプロセスを持っている。 まずはHalideのような高位言語からvISA(仮想命令セット: Virtual Instruction Set Architecture)に変換する。 Virtual Instruction SetはRISC-Vの一部にインスピレーションを受けており、仮想命令という名の通り、 - レジスタファイルは無限 - メモリサイズは無限 - DMAなどの処理は存在せずそのままメモリアクセス などの特徴を持っている。さらに基本的なISAに加えて二次元画像処理向けの命令などもはいっている。

さらにここからvISAをpISA(物理命令セット: Physical Instruction Set Architecture)に変換する。 このvISAを挟むことによって、過去のプロセッサとの互換性の問題を解決することができる。 このあたりはGPUにおけるPTXに似ている(第4章を参照のこと)。

vISAからpISAへの変換も、2ステップで変換する。 まずは「事前バインディング」を行い、次にコードにパッチを当てて「事後バインディング」を行う。 バインディングにあたりパラメータとして、STPのサイズ、Haloのサイズ等を指定する。

pISAVLIWの形式をとっており、全部で119ビットで構成される。 - 43ビット: スカラーレーン。2次元PEアレイの演算も含まれる。 - 38ビット: 2次元アレイの計算 - 12ビット: メモリアクセス - 16ビット: 即値もしくは整数レジスタ - 10ビット: 即値

演算としては、整数演算、飽和付き整数演算、論理演算、シフト、データ転送、除算やLeading Zeroなどの特殊な演算などが含まれる。

pISAVLIW形式であり、Halideのカーネルは短いため、pISAの長さは200~600命令となる。 Pixel Visual Coreは2048個のpISAを保持する命令メモリしか保持していない(28.5kB)。

スカラレーンは、ラインバッファに赤ウエスするシートジェネレータの命令を発行する。 他のPixel Visual Coreのメモリアクセスとは異なり、レイテンシは1クロック以上となる可能性があるので、DMAのようなインタフェースを持っている。 レーンは最初にアドレスと転送サイズを特殊レジスタに設定する。

Pixel Visual Coreの例

図7.36はHalideのコンパイラから生成した、vISAコードである。 この例では画像のぼかしを実行している。 この例では16bitの演算気を使って、x方向の次元を計算し、次にy方向に計算を実行している。 vISAのコードはHalideプログラムのコードにマッチしている。

// vISA inner loop blur in x dimensionns
input.b16  t1 <- _input[x*1+(-1)][y*1+0][0]
input.b16  t2 <- _input[x*1+0][y*1+0][0]
...
div.b16    t9<-t7, st8:
output.b16 _blur_x[x*1+0][y*1+0][0] <- t9
// vISA inner loop blur in y dimension
input.b16  t1 <- _input[x*1+0][y*1+(-1)][0]
input.b16  t2 <- _input[x*1+0][y*1+0][0]
...
div.b16    t9<-t7, st8:
output.b16 _blur_y[x*1+0][y*1+0][0] <- t9

Pixel Visual Core のプロセッサエレメント

Pixel Visual Coreのアーキテクチャを決めるにあたり、最も重要なのは、Haloを処理するためのサポートプロセッサがどれくらいになるかということであった。 Pixel Visual Coreは16×16PEのプロセッサアレイと、2行の追加のHaloアレイをもっており、5×5のステンシル計算が可能になっている。

試行の結果、Haloは16×16のプロセッサアレイのうち20%程度しか消費しないこと明らかになった。

Pixel Visual CoreのPEは積和演算器(Multiply-Accumulate:MAC)を中心に考えられている。 このMACは16bitの乗算器を持っており、32ビットの計算結果を出力する。 パイプラインレジスタMAC中に挿入するとそれだけで電力を消費するため、MACは1サイクルで計算されるようになっている。

PEは2つの16bit ALUをもっており、以下の計算をマイサイクル実行することができる。 - 2つの16bitの計算結果を生成することができる: A op B, C op D - 3項の演算により、1つの16bit計算結果を生成することができる: A op (C op D) - それぞれのオペランドを結合することにより、32bitの演算結果を出力することができる: "A:C op B:D"

2次元ラインバッファとコントローラ

DRAMアクセスはエネルギーを消費するため、Pixel Visual Coreのメモリシステムは、メモリアクセスの回数を最小限にするように設計されている。 そのために「2次元ラインバッファ(two-dimentional line buffer)」というものが採用されている。

ラインバッファの役割は、論理的に異なる2つのカーネルで実行された結果の画像情報などを保持し、次のカーネルに渡すことである。 これにより画像の処理結果を一時的にメモリに退避することを防いでいる。

このため、ラインバッファは以下の4つの機能をサポートしている。

  1. 様々なサイズの2次元ステンシル計算をサポートしなければならない。この計算のサイズは設計時には不明である。
  2. Haloにより、16×16のPEの計算の場合は20×20のピクセルブロックを読み込まなければならず、16×16の計算結果を出力する。
  3. DAGはプログラミングできるため、ラインバッファは任意の2コアにより割り当てられる必要性がある。
  4. いくつかのコアが同一のラインバッファからデータを読み取ることができる必要がある。したがって、ラインバッファは複数の読み込みリクエストを受け付けることができる必要がある。

Pixel Visual Coreのラインバッファは複数の読み込みリクエストを受け付けることのできる2次元FIFOとして構成され、最終的には128KB SRAMインスタンスされている。 20×20のデータを読み取って16×16のデータを書き出すような、サイズの異なる読み書きをサポートするため、FIFOは4×4のピクセルをグループとして構成されている。 ステンシルプロセッサごとに、ランバッファプール(Line Buffer Poll: LBP)が配置されており、論理的に8個のラインバッファを持つ区とができている。

LBPは3レベルの抽象化を行っている。

  1. 最上位の抽象化では、LBPコントローラは8つのLBをサポートしている。各LBは1つのFIFO書き込みを行うことができ、8つのFIFO読み込みを行うことができる。
  2. コントローラはFIFOの最初と最後のポインタを保持している。LBP内のラインバッファのサイズはコントローラにより自由に調整できる。
  3. 物理的なメモリバンクが公営刺され、バンド幅を引き出すように設計されている。Pixel Visual Coreは8つの物理的なメモリバンクを持っており、128bitのインタフェースを持っており、16KBの容量である。

Pixel Visual Coreの実装

最初のPixel Visual Coreは複数のチップに分割されていた。 これは2016年にTSMCの28nmプロセスで製造され、6×7.2mmのサイズであり、426MHzで動作した。 このチップはSIPとして512MBのDRAMを持っており、負荷に応じて187~4500mWを消費した。 チップの30%は ARMv7 A53コアの制御と、MIPI、PCIe, LPDDRインタフェースで消費された。 これらのインタフェースはチップの約半分である23mm2である。