LLVMとコンパイラと投資 Intel® Architecture Code Analyzerの使いどころ
--.--.-- *--

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書く事で広告が消せます。

2011.11.16 *Wed

Intel® Architecture Code Analyzerの使いどころ

Intel® Architecture Code Analyzer(以降IACAと略す)というのは、
sandy bridgeなどの最近のArchitectureのフロントエンドの動作をシミュレーションするツールです。

第2回 x86最適化勉強会で知りました。
IACAの紹介へのリンク

紹介されていた際にも、なんか使いどころがわからん???みたいな話だったのですが、
今回はIACAの用途を紹介したいと思います。

下記のリンクで紹介されているソースコードを例に、どんな出力になるのかを紹介したいと思います。

SSEを使って8flops/clockを実現する

試した環境は、
core i7 2600
gcc-4.6
です。

上記の紹介記事によると、2つの関数が出てきます。
sse_mulps_addps_no_dependency <-- nodepと略す
sse_mulps_addps_forwarding <-- fowardと略す

それぞれをO3でコンパイルし、どのような結果になるのかを紹介します。
※展開はとりあえずなしで

まずは、nodepのO3 展開なし版


---------------------------------------------------------------------------
Intel(R) Architecture Code Analyzer Version - 1.1.3
Analyzed File - nodep.gccO3.out
Binary Format - 32Bit
Architecture - Intel(R) AVX

Analysis Report
---------------
The analyzed block contains one or more instructions with issues.
The throughput and latency cycle counts do not account for those instructions.

Total Throughput: 5 Cycles; Throughput Bottleneck: FrontEnd, Port1
Total number of Uops bound to ports: 24
Data Dependency Latency: 10 Cycles; Performance Latency: 12 Cycles

Port Binding in cycles:
-------------------------------------------------------
| Port | 0 - DV | 1 | 2 - D | 3 - D | 4 | 5 |
-------------------------------------------------------
| Cycles | 4 | 0 | 5 | 4 | 2 | 4 | 2 | 4 | 3 |
-------------------------------------------------------

N - port number, DV - Divider pipe (on port 0), D - Data fetch pipe (on ports
CP - on a critical Data Dependency Path
N - number of cycles port was bound
X - other ports that can be used by this instructions
F - Macro Fusion with the previous instruction occurred
^ - Micro Fusion happened
* - instruction micro-ops not bound to a port
@ - Intel(R) AVX to Intel(R) SSE code switch, dozens of cycles penalty is expe
! - instruction not supported, was not accounted in Analysis

| Num of | Ports pressure in cycles | |
| Uops | 0 - DV | 1 | 2 - D | 3 - D | 4 | 5 | |
------------------------------------------------------------
| ! | ! | ! | ! | ! | ! | ! | ! | ! | ! | | rdtsc
| 2^ | | | | 1 | | X | | 1 | | CP | mov dword ptr [esp
| 2^ | | | | X | | 1 | | 1 | | CP | mov dword ptr [esp
| 1 | | | | 1 | 1 | X | X | | | CP | mov ecx, dword ptr
| 1 | X | | X | | | | | | 1 | | mov eax, 0x200000
| 1 | | | | X | X | 1 | 1 | | | CP | mov ebx, dword ptr
| 1 | X | | X | | | | | | 1 | | nop
| 1 | | | 1 | | | | | | | | lea esi, ptr [esi]
| 1 | 1 | | | | | | | | | | mulps xmm1, xmm0
| 1 | | | 1 | | | | | | | | addps xmm3, xmm2
| 1 | 1 | | | | | | | | | | mulps xmm5, xmm4
| 1 | | | 1 | | | | | | | | addps xmm7, xmm6
| 1 | 1 | | | | | | | | | | mulps xmm1, xmm0
| 1 | | | 1 | | | | | | | | addps xmm3, xmm2
| 1 | 1 | | | | | | | | | | mulps xmm5, xmm4
| 1 | | | 1 | | | | | | | | addps xmm7, xmm6
| 1 | X | | X | | | | | | 1 | | sub eax, 0x1
| 0F | | | | | | | | | | | jnz 0xffffffe3
| ! | ! | ! | ! | ! | ! | ! | ! | ! | ! | | rdtsc
| 2^ | | | | 1 | | X | | 1 | | | mov dword ptr [esp
| 2^ | | | | X | | 1 | | 1 | | | mov dword ptr [esp
| 1 | | | | 1 | 1 | X | X | | | CP | mov esi, dword ptr
| 1 | | | | X | X | 1 | 1 | | | CP | mov edi, dword ptr
---------------------------------------------------------------------------


比較して、forwardのO3 展開なし版です。


---------------------------------------------------------------------------
Intel(R) Architecture Code Analyzer Version - 1.1.3
Analyzed File - foward.gccO3.out
Binary Format - 32Bit
Architecture - Intel(R) AVX

Analysis Report
---------------
The analyzed block contains one or more instructions with issues.
The throughput and latency cycle counts do not account for those instructions.

Total Throughput: 6 Cycles; Throughput Bottleneck: Port2_ALU, Port3_ALU
Total number of Uops bound to ports: 28
Data Dependency Latency: 13 Cycles; Performance Latency: 18 Cycles

Port Binding in cycles:
-------------------------------------------------------
| Port | 0 - DV | 1 | 2 - D | 3 - D | 4 | 5 |
-------------------------------------------------------
| Cycles | 4 | 0 | 5 | 6 | 4 | 6 | 4 | 4 | 3 |
-------------------------------------------------------

N - port number, DV - Divider pipe (on port 0), D - Data fetch pipe (on ports
CP - on a critical Data Dependency Path
N - number of cycles port was bound
X - other ports that can be used by this instructions
F - Macro Fusion with the previous instruction occurred
^ - Micro Fusion happened
* - instruction micro-ops not bound to a port
@ - Intel(R) AVX to Intel(R) SSE code switch, dozens of cycles penalty is expe
! - instruction not supported, was not accounted in Analysis

| Num of | Ports pressure in cycles | |
| Uops | 0 - DV | 1 | 2 - D | 3 - D | 4 | 5 | |
------------------------------------------------------------
| ! | ! | ! | ! | ! | ! | ! | ! | ! | ! | | rdtsc
| 2^ | | | | 1 | | X | | 1 | | | mov dword ptr [esp
| 2^ | | | | X | | 1 | | 1 | | | mov dword ptr [esp
| 1 | | | | 1 | 1 | X | X | | | | mov ecx, dword ptr
| 1 | X | | X | | | | | | 1 | | mov eax, 0x200000
| 1 | | | | X | X | 1 | 1 | | | | mov ebx, dword ptr
| 1 | X | | X | | | | | | 1 | | nop
| 1 | | | 1 | | | | | | | | lea esi, ptr [esi]
| 2^ | 1 | | | 1 | 1 | X | X | | | CP | mulps xmm0, xmmwor
| 1 | | | 1 | | | | | | | CP | addps xmm4, xmm0
| 2^ | 1 | | | X | X | 1 | 1 | | | CP | mulps xmm1, xmmwor
| 1 | | | 1 | | | | | | | CP | addps xmm5, xmm1
| 2^ | 1 | | | 1 | 1 | X | X | | | CP | mulps xmm2, xmmwor
| 1 | | | 1 | | | | | | | CP | addps xmm6, xmm2
| 2^ | 1 | | | X | X | 1 | 1 | | | CP | mulps xmm3, xmmwor
| 1 | | | 1 | | | | | | | CP | addps xmm7, xmm3
| 1 | X | | X | | | | | | 1 | | sub eax, 0x1
| 0F | | | | | | | | | | | jnz 0xffffffdb
| ! | ! | ! | ! | ! | ! | ! | ! | ! | ! | | rdtsc
| 2^ | | | | 1 | | X | | 1 | | | mov dword ptr [esp
| 2^ | | | | X | | 1 | | 1 | | | mov dword ptr [esp
| 1 | | | | 1 | 1 | X | X | | | | mov esi, dword ptr
| 1 | | | | X | X | 1 | 1 | | | | mov edi, dword ptr
---------------------------------------------------------------------------


比較のポイントになるのは、
^ - Micro Fusion happened
のところ。

forwardのほうでは、mulpsとaddps間でmicro fusionしているらしく、スループットが2になってます。
この表示の見方が良く分かってないんですけど、
上下のどっちかのuopとくっついて、スループット2になってるんでしょうかね???

とりあえず、forwardのほうが速くなっている理由は、micro fusionが行われていることらしい。

直感的には、nodepのほうでport0とport1を順に使ってるんだから、
同時に実行してくれてもいいんじゃないか、いいんじゃないか?という気がします。
私はプロセッサ屋じゃないので、よくわからんです。

何となく上記の結果を見て、
内部でmicro fusionした結果、積和演算命令と同じuopに変換されたってことなのかな?
と思い、x86の積和演算を探して実行して比較してみることにしました。
積和演算はAVXと一緒にFMAがあったよなと思い、
vfmadd132ps %ymm1, %ymm3, %ymm5
とか書いてみたけど、illegal instructionでこけて測定できない。
後で知ったのですが、sandy bridgeではFMA未実装らしい。。。

お次に試したのは、AVXのvfmulpsやvfaddpsではどうなるのかなということ。
そしたら驚きの結果が、、
こちらの結果は、fmul/faddと同じだったのですが、

---------------------------------------------------------------------------
asm volatile
(
"vmulps %0, %%xmm0, %%xmm0\n\t"
"vaddps %%xmm0, %%xmm1, %%xmm1\n\t"
"vmulps %0, %%xmm2, %%xmm2\n\t"
"vaddps %%xmm2, %%xmm3, %%xmm3\n\t"
:
:"m"(a[0])
);
---------------------------------------------------------------------------

3opであることを活かし、destとの依存を試しに切ってみたら、、

---------------------------------------------------------------------------
asm volatile
(
"vmulps %0, %%xmm0, %%xmm4\n\t"
"vaddps %%xmm4, %%xmm1, %%xmm1\n\t"
"vmulps %0, %%xmm2, %%xmm5\n\t"
"vaddps %%xmm5, %%xmm3, %%xmm3\n\t"
:
:"m"(a[0])
);
---------------------------------------------------------------------------



-- sse_mulps_addps_no_dependency --
GFLOPS @ 3.40GHz:
  3.009 [flops/clock] = 10.232 [GFLOPS]  (67108864 flops in 22300090 clock = 0.006559 sec)
Throughput:
  0.752 [instructions/clock]   (16777216 instrucions in 22300090 clock)
-- sse_mulps_addps_forwarding --
GFLOPS @ 3.40GHz:
  5.611 [flops/clock] = 19.077 [GFLOPS]  (67108864 flops in 11960588 clock = 0.003518 sec)
Throughput:
  1.403 [instructions/clock]   (16777216 instrucions in 11960588 clock)
-- avx_vmulps_vaddps_forwarding --
GFLOPS @ 3.40GHz:
  11.408 [flops/clock] = 38.788 [GFLOPS]  (67108864 flops in 5882441 clock = 0.001730 sec)
Throughput:
  2.852 [instructions/clock]   (16777216 instrucions in 5882441 clock)


なんと従来秘の3倍、スループット3倍デスヨ


IACAの解析結果

---------------------------------------------------------------------------
Intel(R) Architecture Code Analyzer Version - 1.1.3
Analyzed File - test003.O3.out
Binary Format - 32Bit
Architecture - Intel(R) AVX

Analysis Report
---------------
The analyzed block contains one or more instructions with issues.
The throughput and latency cycle counts do not account for those instructions.

Total Throughput: 5 Cycles; Throughput Bottleneck: Port2_ALU, Port3_ALU
Total number of Uops bound to ports: 21
Data Dependency Latency: 13 Cycles; Performance Latency: 16 Cycles

Port Binding in cycles:
-------------------------------------------------------
| Port | 0 - DV | 1 | 2 - D | 3 - D | 4 | 5 |
-------------------------------------------------------
| Cycles | 3 | 0 | 2 | 5 | 3 | 5 | 3 | 4 | 2 |
-------------------------------------------------------

N - port number, DV - Divider pipe (on port 0), D - Data fetch pipe (on ports
CP - on a critical Data Dependency Path
N - number of cycles port was bound
X - other ports that can be used by this instructions
F - Macro Fusion with the previous instruction occurred
^ - Micro Fusion happened
* - instruction micro-ops not bound to a port
@ - Intel(R) AVX to Intel(R) SSE code switch, dozens of cycles penalty is expe
! - instruction not supported, was not accounted in Analysis

| Num of | Ports pressure in cycles | |
| Uops | 0 - DV | 1 | 2 - D | 3 - D | 4 | 5 | |
------------------------------------------------------------
| ! | ! | ! | ! | ! | ! | ! | ! | ! | ! | | rdtsc
| 2^ | | | | 1 | | X | | 1 | | | mov dword ptr [ebp
| 2^ | | | | X | | 1 | | 1 | | | mov dword ptr [ebp
| 1 | | | | 1 | 1 | X | X | | | | mov ecx, dword ptr
| 0* | | | | | | | | | | | xor eax, eax
| 1 | | | | X | X | 1 | 1 | | | | mov ebx, dword ptr
| 1 | 1 | | X | | | | | | X | | data16 nop
| 2^ | 1 | | | 1 | 1 | X | X | | | CP | vmulps xmm4, xmm0,
| 1 | | | 1 | | | | | | | CP | vaddps xmm1, xmm1,
| 2^ | 1 | | | X | X | 1 | 1 | | | CP | vmulps xmm5, xmm2,
| 1 | | | 1 | | | | | | | CP | vaddps xmm3, xmm3,
| 1 | X | | X | | | | | | 1 | | add eax, 0x1
| 1 | X | | X | | | | | | 1 | | cmp eax, 0x200000
| 0F | | | | | | | | | | | jnz 0xffffffe4
| ! | ! | ! | ! | ! | ! | ! | ! | ! | ! | | rdtsc
| 2^ | | | | 1 | | X | | 1 | | | mov dword ptr [ebp
| 2^ | | | | X | | 1 | | 1 | | | mov dword ptr [ebp
| 1 | | | | 1 | 1 | X | X | | | | mov esi, dword ptr
| 1 | | | | X | X | 1 | 1 | | | | mov edi, dword ptr
---------------------------------------------------------------------------


うーん、forwardとほぼ同じです。
OoOのほうで、何かいいことあるのでしょうかね。

とりあえずperfで調べてみる。
perfの使いかた

最初のmulpsとaddpsで版

---------------------------------------------------------------------------
elise@elise-desktop:~/language/icc/work/sse$ perf stat forward.out
-- sse_mulps_addps_forwarding --
GFLOPS @ 3.40GHz:
6.686 [flops/clock] = 22.733 [GFLOPS] (67108864 flops in 10036803 clock = 0.002952 sec)
Throughput:
1.672 [instructions/clock] (16777216 instrucions in 10036803 clock)

Performance counter stats for 'forward.out':

3.506812 task-clock-msecs # 0.951 CPUs
1 context-switches # 0.000 M/sec
0 CPU-migrations # 0.000 M/sec
115 page-faults # 0.033 M/sec
12606988 cycles # 3595.000 M/sec
10922084 instructions # 0.866 IPC
9044 cache-references # 2.579 M/sec
2792 cache-misses # 0.796 M/sec

0.003687630 seconds time elapsed
---------------------------------------------------------------------------



AVXのvmulpsとvaddps(レジスタはsrcを破壊的に使用)

---------------------------------------------------------------------------
elisese@elise-desktop:~/language/icc/work/sse$ perf stat avxforward2.out
-- avx_vmulps_vaddps_forwarding2 --
GFLOPS @ 3.40GHz:
6.721 [flops/clock] = 22.853 [GFLOPS] (67108864 flops in 9984227 clock = 0.002937 sec)
Throughput:
1.680 [instructions/clock] (16777216 instrucions in 9984227 clock)

Performance counter stats for 'avxforward2.out':

3.477048 task-clock-msecs # 0.945 CPUs
1 context-switches # 0.000 M/sec
0 CPU-migrations # 0.000 M/sec
114 page-faults # 0.033 M/sec
12495889 cycles # 3593.821 M/sec
10922680 instructions # 0.874 IPC
8583 cache-references # 2.468 M/sec
2166 cache-misses # 0.623 M/sec

0.003680900 seconds time elapsed
---------------------------------------------------------------------------


AVXのvmulpsとvaddps(srcとdestは別レジスタの版)

---------------------------------------------------------------------------
elise@elise-desktop:~/language/icc/work/sse$ perf stat avxforward.out
-- avx_vmulps_vaddps_forwarding --
GFLOPS @ 3.40GHz:
11.272 [flops/clock] = 38.325 [GFLOPS] (67108864 flops in 5953505 clock = 0.001751 sec)
Throughput:
2.818 [instructions/clock] (16777216 instrucions in 5953505 clock)

Performance counter stats for 'avxforward.out':

2.308656 task-clock-msecs # 0.932 CPUs
0 context-switches # 0.000 M/sec
0 CPU-migrations # 0.000 M/sec
115 page-faults # 0.050 M/sec
8304734 cycles # 3597.216 M/sec
10915629 instructions # 1.314 IPC
8383 cache-references # 3.631 M/sec
2481 cache-misses # 1.075 M/sec

0.002476608 seconds time elapsed
---------------------------------------------------------------------------


IPCの値が高いのは分かるんだけど、IACAの分析ではフロントまで同じなんだよね。
謎です。。
avx_sample
CATEGORY : 日記 | THEME : ソフトウェア開発 | GENRE : コンピュータ

COMMENT

Comment Form


秘密にする
 

TRACKBACK

TrackBack List


検索フォーム



プロフィール

nothingcosmos

Author:nothingcosmos
コンパイラと投資に関して
自分の考えや、周辺技術の紹介等をしています。
コメント・質問はお気軽にどうぞ。

LLVM wiki
twitter:nothingcosmos



リンク

このブログをリンクに追加する



最新記事



カテゴリ



最新トラックバック



月別アーカイブ



05
--
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
--
Copyright © LLVMとコンパイラと投資 All Rights Reserved.
テンプレート配布者: サリイ  ・・・  素材: bee  ・・・  FC2ブログ