OpenCLメモ (その2) - Intel GPUの構造

The Compute Architecture of Intel Processor Graphics Gen9と、2014 OpenCL Optimization Guideをたよりに、Intel GPUの構造を確認した。

構造を理解していないと、いろいろな罠にひっかかって速度が出ないというのが、GPUの特徴である。



GPUのおおまかな構造はこんな感じ。i7 6700Kほか多くのCPUの内蔵GPUであるHD Graphics 530はGT2とよばれる規模のGPUで、24EUと言われる。この24EUのまとまりをsliceと呼び、これがリングバスを通してメモリコントローラにつながっている。



実際には1つのslice中は3つのsubsliceに分かれていて、1subsliceあたり8EUを搭載することで、24EUとなっている。



EUはいくつかの演算器の集合で、
・128bit SIMD演算器(ALU/FPU) x2
・Sendユニットx1 (メモリアクセスとかEUの外にアクセスする処理全般)
・Branchユニットx1
・256bitレジスタ x128 x 7スレッド分
を持つ。

2基の128bit SIMD演算器を合わせると、以下のような計算のいずれかを毎cycle発行可能である。
・16 x FP16
・8 x FP32
・2 x FP64 (片方のユニットしか実行できない)
・16 x INT16
・8 x INT32



EUでの計算は基本的にSIMD演算器を使うことになるので、命令もそれにそってSIMD型の命令となっている。コンパイラは、プログラムに応じて、8 / 16 / 32 のwork itemを1つのスレッドにまとめて実行する。(SIMD-8 / SIMD-16 / SIMD-32)

実際には、SIMD-32の演算器は存在しないので、例えばSIMD-8 x4などに分解されて実行される。

EUは最大7スレッドを(切り替えながら)同時に処理することができる。なるべく多くのスレッドをEUに突っ込むことで、演算器の使用率を高く保ち、演算効率を上げることができる。

8つのEUが集まってsubsliceを構成する。subsliceには8つのEUからのデータアクセスを処理するData Portが存在するが、読み書き双方向にそれぞれ64byte/cycleであり、EU8つの演算力と比べれば十分なデータ供給力があるとはいえず、なるべくEU内のレジスタを使用した演算を行うことが効率よく計算するためには必要であることがわかる。

ただし、Data Port以外にOpenCLのimageNdを使用した場合のみ使えるアクセス方法が存在し、これがいわゆるSamplerキャッシュ(テクスチャキャッシュ)である。これは読み込み専用であるが、64byte/cycleの帯域と4KBのL1キャッシュ + 24KBのL2キャッシュを持つ。



Data PortはEUからのメモリアクセスをまとめて効率化することが可能である。これをコアレスアクセスという。例えば、SIMD-16などであれば、そのスレッドは16work itemについて一度に処理するわけだが、その16work itemのメモリアクセスが1つのキャッシュライン(64byte以内)であれば、これをまとめてアクセスするすることで効率よくアクセスするというものである。

GPU演算でメモリアクセスの効率を上げることは非常に重要なため、連続するwork itemのメモリアクセスが必要とするキャッシュラインをなるべく少なくし、取り込んだデータに無駄がないようにする必要がある。基本的にメモリアクセスはキャッシュライン(64byteの塊)を単位として行われるので、これを意識すると効率が良くなる。

例1のように、連続するwork itemのアクセスが、ひとつのキャッシュラインに収まっていれば、1回のメモリアクセスですみ、効率が良い。

例1


例2のように、飛び飛びのアクセスであると、複数のキュッシュラインからデータを取ってくることになり、アクセス効率が低下する。また、読み込んでも使用していないデータが多く、無駄にメモリ帯域を使っていることになる。

例2


連続であればなんでも良いかというと、そういうわけではなく、先頭のアドレスがキャッシュラインとずれていると、キャッシュラインをまたぐことになよって、2回のメモリアクセスが必要になり、効率が悪化する。

例3



同じキャッシュラインへのアクセスであれば問題ないので、例4のように、逆順でも問題はない。

例4


このように、先頭のwork itemのアクセス先のアライメントをとり、work itemが連続したアクセスとすることで、なるべくキャシュラインをまたがないようにして、メモリアクセス効率を高めることが重要である。


最後に3つのsubsliceとL3キャッシュ(512KB)が1つのsliceを形成する。Data PortからのアクセスやSamplerからのアクセスはすべてこのL3キャッシュを通り、64byte/cycleでリングバスに接続される。



Shared Local Memoryはsubsliceあたり64KB(計192KB)まで利用可能な特殊なメモリ領域で、work group内で共有して利用することができる。また、通常のメモリアクセスよりも比較的多様なアクセスパターンを高速に処理できるという特徴を持つ。そのため、work group内のwork itemが、他のwork itemの計算結果を使用したい場合、このSLMを経由して渡してやると効率的にやり取りできる。また、work group内のwork itemが同じ値を何度も重複して利用する場合に、明示的にSLMにキャシュしてやると、高速化につながることがある。

ただ、このSLMがsubsliceの外にあるため、必ずDataPortを経由せざるを得ず、EUからのアクセス帯域に制限が生じていて、そこまで高速というわけではないので、注意が必要である。SLMはwork group内で共有すればよく、同じWork groupのwork itemは必ず同じsubsliceで実行されるのだとすれば、SLMはsubslice内にあればよいはずで、なぜSLMをsubsliceの外に実装しているのかが、Intelの実装で不思議な点である。(例えば、NVIDIA PascalのsharedメモリはSMの中にある)

ちなみに、sliceが1つなのはHD Graphics 530が24EUのGT2だからで、Skylakeにはさらに48EUのGT3、72EUのGT4があり、この場合はsliceの数が2、3と増えることになる。



というわけでざっと資料を見るとこんな感じ。

やはり、性能を出すにはwork groupの構成とか、work itemのメモリアクセスとか、そのあたりを注意する必要があるように思う。



続き>>




OpenCLメモリスト
OpenCLメモ (その1) - かんたんな計算
OpenCLメモ (その2) - Intel GPUの構造 (いまここ)
OpenCLメモ (その3) - work sizeの調整
OpenCLメモ (その4) - 転送(コピー)の排除 (USE_HOST_PTR)
OpenCLメモ (その5) - 転送(コピー)の排除 (SVM : OpenCL 2.0)
OpenCLメモ (その6) - imageの使用
OpenCLメモ (その7) [終] - reductionとshared local memory(SLM)の使用


コメントの投稿

非公開コメント

プロフィール

rigaya

Author:rigaya
アニメとか見たり、エンコードしたり。
連絡先: [email protected]
github twitter

最新記事
最新コメント
カテゴリ
月別アーカイブ
カウンター
検索フォーム
いろいろ
公開中のAviutlプラグインとかのダウンロード

○Aviutl 出力プラグイン
x264guiEx 3.xx
- x264を使用したH264出力
- x264guiExの導入紹介動画>
- x264guiExの導入
- x264guiExのエラーと対処方法>
- x264.exeはこちら&gt

x265guiEx
- x265を使用したH.265/HEVC出力
- x265guiExの導入>
- x265.exeはこちら&gt

QSVEnc + QSVEncC
- QuickSyncVideoによるHWエンコード
- QSVEnc 導入/使用方法&gt
- QSVEncCオプション一覧&gt

NVEnc + NVEncC
- NVIDIAのNVEncによるHWエンコード
- NVEnc 導入/使用方法&gt
- NVEncCオプション一覧&gt

VCEEnc + VCEEncC
- AMDのVCE/VCNによるHWエンコード
- VCEEnc 導入/使用方法&gt
- VCEEncCオプション一覧&gt

svtAV1guiEx
- SVT-AV1によるAV1出力
- svtAV1guiExの導入>
- SVT-AV1単体はこちら&gt

VVenCguiEx
- VVenCによるVVC出力
- VVenCguiExの導入>

ffmpegOut
- ffmpegを使用した出力
- ffmpegOutの導入>


○Aviutl フィルタプラグイン
自動フィールドシフト
- SSE2~AVX512による高速化版
- オリジナル: aji様

clcufilters 
- OpenCL/CUDAのGPUフィルタ集
- 対応フィルタの一覧等はこちら

エッジレベル調整MT
- エッジレベル調整の並列化/高速化
- SSE2~AVX512対応
- オリジナル: まじぽか太郎様

バンディング低減MT
- SSE2~AVX512による高速化版
- オリジナル: まじぽか太郎様

PMD_MT
- SSE2~AVX512による高速化版
- オリジナル: スレ48≫989氏

透過性ロゴ (ミラー)
- SSE2~FMA3によるSIMD版
- オリジナル: MakKi氏

AviutlColor
- BT.2020nc向け色変換プラグイン
- BT.709/BT.601向けも同梱

○その他
Amatsukaze改造版
- AmatsukazeのAV1対応版

tsreplace
- tsの映像のみを置き換えて圧縮

rkmppenc
- Rockchip系SoCのhwエンコーダ

fawutil
- FAW(FakeAACWave)⇔aac変換
- 二重音声の取り扱いにも対応

x264afs (ミラー)
- x264のafs対応版

aui_indexer (使い方>)
- lsmashinput.aui/m2v.auiの
 インデックス事前・一括生成

auc_export (ミラー使い方>)
- Aviutl Controlの
 エクスポートプラグイン版
 エクスポートをコマンドから

aup_reseter
- aupプロジェクトファイルの
 終了フラグを一括リセット

CheckBitrate (使い方)
- ビットレート分布の分析(HEVC対応)

チャプター変換 (使い方>)
- nero/appleチャプター形式変換

エッジレベル調整 (avisynth)
- Avisynth用エッジレベル調整

メモリ・キャッシュ速度測定
- スレッド数を変えて測定
- これまでの測定結果はこちら

○ビルドしたものとか
L-SMASH (ミラー)
x264 (ミラー)
x265 (ミラー)
SVT-AV1 (ミラー)

○その他
サンプル動画
その他

○読みもの (ミラー)
Aviutl/x264guiExの色変換
動画関連ダウンロードリンク集
簡易インストーラの概要

○更新停止・公開終了
改造版x264gui
x264guiEx 0.xx
RSSリンクの表示
リンク
QRコード
QR