一度覚えたけど忘れてしまったのでメモ
SIMDとかGPGPUとかやる時に地味に必要な知識
適当に調べたので間違ってる可能性あり
CPU
1コアあたり1clockあたりの積和スループット
| |||||||||||||||||||||||||||
(2018/11/8追記)Zen1ではSIMDスループット低くどうなんだと思っていたけど、まぁなんだかんだコア数でカバーしてて結果悪くはないと思ってた。Zen2は14nm→7nmになってSIMD幅2倍になり、これが本当ならば凄いと思う→すごかった!
GPU
1SM(1CU)あたりの CUDAコア数(PE数) | warp実行 cycle | 1CUDAコアあたりの レジスタ(32bit)本数 | 1SMあたりの 共有メモリ | |
Tesla | 8 | 4 | ? | ? |
Fermi | 32 | 2 | 1024 | 48KB |
Kepler | 192 | 2 | 341.33 | 48KB |
Maxwell | 128 | 1 | 512 | 64-96KB? |
Pascal(GP104) | 128 | 1 | 1024 | 64KB |
Volta | 64 | 2 | 1024 | 128KB? |
Turing | 64 | 2 | 1024 | 96KB? |
Ampere | 64 | 2 | 1024 | 164KB? |
GCN(Tahiti) | 64 | 4 | 1024 | 64KB |
RDNA | 64 | 1 | 1024 | 64KB |
参考
https://news.mynavi.jp/photo/article/20170814-vega/images/004l.jpg
etc
余談
一般的にGPUプログラミングにおいて命令レイテンシ隠ぺいとメモリアクセスレイテンシ隠蔽のため、warp(≒wavefront)をたくさん立ち上げることが良いとされる。
一方チューニングされたコードは、例えば1SM内で128threadを立ち上げ、その128threadで共有メモリとレジスタを使いきる・・みたいな処理が考えられる。
その際1SM内で使える共有メモリの最大量やレジスタ量が分かっていないと何かと不便だと思った。またプロファイラ使わないでもこれでOccupancyがだいたい想定できたりする。
「warp実行cycle」についてだが、AMDではwarpでなくwavefrontという。それぞれNVIDIA GPUでは1warp=32thread、AMDのGCNは1wavefront=64thread、AMDのRDNAは1wavefront=32threadとなってて並列処理の最小単位みたいなもので、これを何サイクルで実行するのかという項目。
GCNでいうと1CU(SMみないなもん)=64PE(CUDAコアみたいなもん)なのだが、64PE(processing element)で64threadを1cycleで実行するというものではない
1CUあたりせっかく64PEあるのに、16PEが4cycleで1wavefrontを実行するという形になっている。もちろんwavefrontがたくさんある状況下では64PEが4cycleで4wavefrontを処理するためスループットはちゃんとでるのだが。
もし例えばOpenCLなんかのコードでgroup size(=local work size)が64で、1CU内で64threadが共有メモリとレジスタをほぼ使い切るような処理を書いてしまうと、16PEがその1wavefrontを実行しその間残りの48PEがお留守になってしまうという痛ましいことになる。
なのでgroup sizeを64じゃなく256でやるか、どうしても64のままがいいならその分共有メモリやレジスタの使う量を1/4に減らさないとPEを使い切ることができない。
昔原因がわからなくハマって最近調べてやっと分かったため上記にまとめてメモを残そうと思った