目次
結局Bulldozerってどうなの
Software Optimization Guide for AMD Family 15h Processorsより
思想としては、
ということなんだと思われる。
実際どうなっているか命令単位でベンチマークしてみる
手元(A8-4500M)で動かした時の結果(なんかTurbo Boost止められなかったので実際には1.9GHzのrdtscクロックが2.3GHzのCPUクロックにあうように値調整してます)
$ bench-ipc <ループ回数> <Thread1 affinity> <Thread2 affinity> ... とかやって使う
$ bench-ipc 1000000 0 2 3 # 100万回ループして、スレッド0をコア0に、スレッド1をコア2に、スレッド2をコア3に割り当てる ipc4 0:00000001:2.074932 1:00000010:2.051553 2:00000100:1.090766 ^ ^ ^ | | | | | 命令を実行するのにかかったクロック | | | アフィニティマスク | スレッドID
これでスレッド割り当てと IPC の関係を見る
ADD は EX、MOVのロードは AGLU なので、これをあわせれば IPC 4 出る
add ecx, 1 add edx, 1 mov esi, mem[0] mov edi, mem[0] ======================================== $ ./rdtsc.exe 100000 0 1 2 ipc4 0:00000001:2.074932 1:00000010:2.051553 2:00000100:1.090766
Core 0,1 は、同じモジュール、 Core2は別モジュールになっていて、 Core 0,1 では、4命令あたり 2clk、 Core 2は、4命令あたり 1clkで実行できる。
sse の整数演算は、FPUで実行されるので、シングルスレッドなら整数演算を4命令/clkで実行できる。これは(多分)x86史上最強のALUを積んでるということである。
add ecx ,1 add edx ,1 paddd xmm0, xmm0 paddd xmm1, xmm1 add ecx, 1 add edx, 1 paddd xmm2,xmm2 paddd xmm3,xmm3 # paddd はレイテンシ2あるので埋めるために8命令実行する ======================================== add4x add4x 0:00000001:4.070786 1:00000010:4.070721 2:00000100:2.067680
Core 2 では、8命令あたり 2clk で実行できる。
L1D は、コアで占有されていて、2read できるので、2スレッドで4read できるはず…!と見せかけてできない…!
add ecx, mem add edx, mem ======================================== add2_mem 0:00000001:2.004254 1:00000010:2.001533 2:00000100:1.108393
なんで? Agner さんの microarchitecture.pdf にもなんか出ないとか書いてあって
No explanation has been found for this reduced throughput.
Agnerさんをもってしてもよくわからない現象っぽい。
1コアでFPU占有すれば、浮動小数演算は 2op/clk 出る
xorps xmm0, xmm0 addss xmm0, xmm0 xorps xmm0, xmm0 addss xmm0, xmm0 ======================================== fadd2 0:00000001:2.069074 1:00000010:2.063987 2:00000100:1.038717
シングルスレッドならmul x 2 も可能である。これは(多分)x86史上最強のFPUを積んでいるということである。
Bulldozer 出るか出ないかの頃は 2ch でよく L2 write-through() とか書いてあったが実際どうなのか。
実際には、Storeした直後の値は、StoreBufferに入っていて、それを読めばStore-Forwardingされるから、実害は控えられるはず…
なら、store forwardingミスったらどうなるの?というのが 2
# store_forwarding mov [mem], ecx mov ecx, [mem] # store_forwarding2 (32bit のうち下位8bitに書き込んだ直後に32bit読む) mov [edi+4], cl mov ecx, [edi+1] ======================================== store_forwarding 0:00000001:8.582095 1:00000010:8.133118 2:00000100:8.219721 store_forwarding2 0:00000001:34.957176 1:00000010:34.570470 2:00000100:30.401867
結構大きい…が、いきなりメモリレイテンシ分止まるというわけではないみたい。(どういう実装なんだろうか?)
シングルスレッド性能だけを見ると
→ 史上最強のx86の誕生か!?
(シャッフルみたいにスループット下がってる命令もあるので若干誇張があります)
ほんまかよ…?
FPUをヘヴィに使って、簡単なベンチマークということで、himenoBMTを動かしてみる
cl(64bit ver 16.00) で /O2 /Zi /DSSMALL でビルド
結果
…史上最強とはなんだったのか…
クロック比を考えても、約1.7倍の性能差が存在しているようにしか見えない。
Agnerさんによると、シングルスレッドだと命令フェッチが MAX 22byte しか出ないとか書いてある。 命令フェッチの帯域の計測方法よく知らないので実測してないが、 64bitのhimenoBMTだと、 グローバルに変数置かれてる都合上、命令が、 REX + SSE のプレフィクスx2 + opcode + modrm + sib + disp32 で、 9byteになっているものがある。 これだと、Max 22byteのフェッチ幅だと、2命令/clkしかissueできない…
(と、勉強会で説明したのですが、その時の指摘にもあったように、Nehalem/Core2が16byteフェッチでそれよりは大きいので、特別これが弱いとするのはちょっとおかしいかもしれないです)
himenoBMTをふたつ起動して、processexplorerでaffinity設定して、 A8 ではモジュールに乗るように、i7ではコアに乗るようにした。結果(スレッドあたり)↓
(ivyはシングルスレッドの丁度半分でシングルスレッドから完全に依存見つけてるんだろうかすごい)
クロック比を考慮すると、差は6%まで縮んでいる。
つまり、依存関係が無い命令を発行できれば、カタログ値に見合った性能を発揮している。
→ なんか依存関係を見つけられてないのでは。
似たような問題をK10 vs CoreMAの時にも見た(http://int.main.jp/txt/k10/#sec6。つまり、RSの深さがIvyよりも足りないのではないかという説。
最適化マニュアルには、FPUはRSの深さ60とか書いてあって、Sandyよりもリッチなのだが、 K10と同じく合計60で、実際には4本の各パイプごとに深さ15づつぐらいしか無いのだろうと予想される。
前と同じ方法で測った。つまり、命令の依存を長くしていって、どのぐらいでレイテンシ見えてくるか測った。
mulss
addss
横軸が命令の依存の長さ。縦軸が命令あたりの平均クロック数。レイテンシを隠蔽できれば理論スループット(addss,mulssともに1)に近付くはず
どう見ても60もあるように見えない。15x4 だと考えたほうが妥当だと思われる。
深さ15は、K10の14よりも増えているが、浮動小数やSSE命令のいくつかは地味にレイテンシ増えてるので、 強化されていると言えるかは微妙ではないか
himenoBMTからわかること整数もやっておくか。
(Dhrystoneはちょろっとした関数を呼ぶだけなので、現代のアーキテクチャのベンチマークとしては向かないと思いそうだが、むしろ昨今のプログラムは小さいBBが並んでるみたいなのが多いので、むしろ現代のソフトウェアにあっているのではないかという説)
印象を書くなら、
結果
…しじょうさいきょうのx86さん… (クロック比を考慮しても30%ぐらい)
マルチスレッドで動かすと↓
クロック比考慮するとちょうど同じくらい
というように見える。
Software Optimization Guide for AMD Family 15h Processors : 公式
The microarchitecture of Intel, AMD and VIA CPUs: An optimization guide for assembly programmers and compiler makers : 上で "Agner さんの"とか書いてるやつ
この文書はx86/x64最適化勉強会4のために書かれました。