FC2カウンター FPGAの部屋 2015年07月11日
FC2ブログ

FPGAやCPLDの話題やFPGA用のツールの話題などです。 マニアックです。 日記も書きます。

FPGAの部屋

FPGAの部屋の有用と思われるコンテンツのまとめサイトを作りました。Xilinx ISEの初心者の方には、FPGAリテラシーおよびチュートリアルのページをお勧めいたします。

clang の最適化と自動ベクトル化を使用した時の性能

2015/07/14:修正 時間計測にバグがあったので、全面的に記事を修正しました。miyox さん、ありがとうございました)

ZYBOのUbuntu14.04 LTSにclangをインストールしてコンパイル”で、clang-3.4 + llvm-3.4 でC がコンパイルできるようになったので、clang の最適化オプションや自動ベクトル化・オプションを付けてコンパイルした時にどのくらいの性能向上があるのかを検証する。

実行環境はZYBOで、Dual Cortex-A9 650 MHz プロセッサを持ち、Ubuntu 14.04 LTS が動作している。

clang ではgcc の様に warning を取り除けなかったので、各最適化オプションの実行形式ファイルを個別に作製して、それを実行して、ラプラシアンフィルタ処理のみの時間を計測している。

最初に、laplacian_filter.c の最適化テストを行った。下にコンパイル・コマンドを示す。

clang laplacian_filter.c -o laplacian_filter1
clang -O1 laplacian_filter.c -o laplacian_filter1_O1
clang -O2 laplacian_filter.c -o laplacian_filter1_O2
clang -O3 laplacian_filter.c -o laplacian_filter1_O3
clang -Os laplacian_filter.c -o laplacian_filter1_Os
clang -mcpu=cortex-a9 -mfpu=neon -mfloat-abi=hard -O3 laplacian_filter.c -o laplacian_filter1_n3

実行結果を下に示す。自動ベクトル化オプションを付けてコンパイルした実行形式ファイルについては、以下のコマンドで、

objdump -S -d laplacian_filter1_n3 | grep "vmov"

NEONの命令の vmov があるかないかでベクトル化されているかどうかを調査した。
clang_2_150711.png
自動ベクトル化はされて無かった。

laplacian_filte2r.c の最適化テストを行った。下にコンパイル・コマンドを示す。

clang laplacian_filter2.c -o laplacian_filter2
clang -O1 laplacian_filter2.c -o laplacian_filter2_O1
clang -O2 laplacian_filter2.c -o laplacian_filter2_O2
clang -O3 laplacian_filter2.c -o laplacian_filter2_O3
clang -Os laplacian_filter2.c -o laplacian_filter2_Os
clang -mcpu=cortex-a9 -mfpu=neon -mfloat-abi=hard -O3 laplacian_filter2.c -o laplacian_filter2_n3

自動ベクトル化オプションを付けてコンパイルした実行形式ファイルについては、以下のコマンドで、

objdump -S -d laplacian_filter2_n3 | grep "vmov"

NEONの命令の vmov があるかないかでベクトル化されているかどうかを調査した。
clang_3_150711.png
自動ベクトル化されているようだ。

laplacian_filte3r.c の最適化テストを行った。下にコンパイル・コマンドを示す。

clang laplacian_filter3.c -o laplacian_filter3
clang -O1 laplacian_filter3.c -o laplacian_filter3_O1
clang -O2 laplacian_filter3.c -o laplacian_filter3_O2
clang -O3 laplacian_filter3.c -o laplacian_filter3_O3
clang -Os laplacian_filter3.c -o laplacian_filter3_Os
clang -mcpu=cortex-a9 -mfpu=neon -mfloat-abi=hard -O3 laplacian_filter3.c -o laplacian_filter3_n3

自動ベクトル化オプションを付けてコンパイルした実行形式ファイルについては、以下のコマンドで、

objdump -S -d laplacian_filter3_n3 | grep "vmov"

NEONの命令の vmov があるかないかでベクトル化されているかどうかを調査した。
clang_4_150711.png
こちらも自動ベクトル化されているようだ。

laplacian_filter4.c の最適化テストを行った。下にコンパイル・コマンドを示す。

clang laplacian_filter4.c -o laplacian_filter4
clang -O1 laplacian_filter4.c -o laplacian_filter4_O1
clang -O2 laplacian_filter4.c -o laplacian_filter4_O2
clang -O3 laplacian_filter4.c -o laplacian_filter4_O3
clang -Os laplacian_filter4.c -o laplacian_filter4_Os
clang -mcpu=cortex-a9 -mfpu=neon -mfloat-abi=hard -O3 laplacian_filter4.c -o laplacian_filter4_n3

自動ベクトル化オプションを付けてコンパイルした実行形式ファイルについては、以下のコマンドで、

objdump -S -d laplacian_filter4_n3 | grep "vmov"

NEONの命令の vmov があるかないかでベクトル化されているかどうかを調査した。
clang_5_150711.png
自動ベクトル化はされて無かった。

laplacian_filter.c の自動ベクトル化の-Oフラグによる違いを検証した。それぞれの実行形式ファイルはn の後の添字が最適化フラグ -O の値を示している。
更に、objdump -S -d laplacian_filter1_n? | grep "vmov" -Cをそれぞれの実行形式ファイルについて実行して自動ベクトル化されているかどうかを確認した。返り値が 0 でない数字の実行形式ファイルが自動ベクトル化されている。
clang_6_150711.png

laplacian_filte2r.c の自動ベクトル化の-Oフラグによる違いを検証した。それぞれの実行形式ファイルはn の後の添字が最適化フラグ -O の値を示している。
更に、objdump -S -d laplacian_filter2_n? | grep "vmov" -Cをそれぞれの実行形式ファイルについて実行して自動ベクトル化されているかどうかを確認した。返り値が 0 でない数字の実行形式ファイルが自動ベクトル化されている。
clang_7_150711.png

laplacian_filte3r.c の自動ベクトル化の-Oフラグによる違いを検証した。それぞれの実行形式ファイルはn の後の添字が最適化フラグ -O の値を示している。
更に、objdump -S -d laplacian_filter3_n? | grep "vmov" -Cをそれぞれの実行形式ファイルについて実行して自動ベクトル化されているかどうかを確認した。返り値が 0 でない数字の実行形式ファイルが自動ベクトル化されている。
clang_8_150711.png

laplacian_filter4.c の自動ベクトル化の-Oフラグによる違いを検証した。それぞれの実行形式ファイルはn の後の添字が最適化フラグ -O の値を示している。
更に、objdump -S -d laplacian_filter4_n? | grep "vmov" -Cをそれぞれの実行形式ファイルについて実行して自動ベクトル化されているかどうかを確認した。返り値が 0 でない数字の実行形式ファイルが自動ベクトル化されている。
clang_9_150711.png

以前の gcc 4.6 と 4.8 の結果を示す。自動ベクトル化された実行形式ファイルはフォントの色を赤に変更してある。
clang_10_150711.png

今回の clang-3.4, llvm-3.4 の結果を示す。自動ベクトル化された実行形式ファイルはフォントの色を赤に変更してある。
clang_11_150711.png

clang の実行時間データの中で最速のデータは、clang の 自動ベクトル化、-Osの時の laplacian_filter2 だったが、gcc-4.8 の実行時間が一番速いようだ。

自動ベクトル化すると、gcc, clang 共に速くなることがわかった。
gcc-4.6 で最速の77.7 ms が自動ベクトル化された時の実行時間だ。自動ベクトル化されていない時は 82.2 ms だったのが表からわかる。これは、83.6 ms / 77.7 ms ≒ 1.08 倍に速くなっている。

gcc-4.8 で、自動ベクトル化された最速の 74.4 ms の自動ベクトル化なしの場合は、82.2 ms だった。これは、82.2 ms / 74.4 ≒ 1.10 倍に速くなっている。

clang-3.4 で、自動ベクトル化された最速の 87.4 ms の自動ベクトル化なしの場合は、105 ms だった。これは、105 ms / 87.4 ms ≒ 1.20 倍速くなっている。

オプションによる実行時間の差が大きい事があるのが分かったので、少なくとも最適化オプションは全て確かめてみるべきだろうと思う。
  1. 2015年07月11日 20:07 |
  2. Zynq
  3. | トラックバック:0
  4. | コメント:0