FC2カウンター FPGAの部屋 OpenMPでのラプラシアンフィルタの実行速度2

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

FPGAの部屋

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

OpenMPでのラプラシアンフィルタの実行速度2

OpenMPでのラプラシアンフィルタの実行速度”の続き。

Vengineer さんからツイッターで、”forループ内のローカル変数をプラグマ内で定義しないと、おかしくなりますよ”とのアドバイスを頂いた。調べてみると、”#pragma omp parallel for”の後に”private(list)”を付ける必要があるようだ。
C言語による OpenMP 入門 ”の12ページ、”5.1 private(list) ”を参照すると、各スレッドで独自の変数値を持つためには、private 指示子が必要なようだ。

最初に laplacian_filter.c だが、以下の図の様にCソースコードを修正した。
OpenMP_14_150717.png

2つ目の for ループの前に、

#ifdef _OPENMP
#pragma omp parallel for private(lap_fil_val, fl, sl, tl, a, b)
#endif

を置いた。

このCソースコードを以下のコマンドで、コンパイル、実行、NEON命令の有無を調査した。

gcc -fopenmp laplacian_filter.c -o laplacian_filter1_mp
gcc -fopenmp -O1 laplacian_filter.c -o laplacian_filter1_mpO1
gcc -fopenmp -O2 laplacian_filter.c -o laplacian_filter1_mpO2
gcc -fopenmp -O3 laplacian_filter.c -o laplacian_filter1_mpO3
gcc -fopenmp -Os laplacian_filter.c -o laplacian_filter1_mpOs
gcc -fopenmp -mcpu=cortex-a9 -mfpu=neon -ftree-vectorize -mvectorize-with-neon-quad -ffast-math laplacian_filter.c -o laplacian_filter1_mpn
gcc -fopenmp -mcpu=cortex-a9 -mfpu=neon -ftree-vectorize -mvectorize-with-neon-quad -ffast-math -O1 laplacian_filter.c -o laplacian_filter1_mpn1
gcc -fopenmp -mcpu=cortex-a9 -mfpu=neon -ftree-vectorize -mvectorize-with-neon-quad -ffast-math -O2 laplacian_filter.c -o laplacian_filter1_mpn2
gcc -fopenmp -mcpu=cortex-a9 -mfpu=neon -ftree-vectorize -mvectorize-with-neon-quad -ffast-math -O3 laplacian_filter.c -o laplacian_filter1_mpn3
gcc -fopenmp -mcpu=cortex-a9 -mfpu=neon -ftree-vectorize -mvectorize-with-neon-quad -ffast-math -Os laplacian_filter.c -o laplacian_filter1_mpns
./laplacian_filter1_mp
./laplacian_filter1_mpO1
./laplacian_filter1_mpO2
./laplacian_filter1_mpO3
./laplacian_filter1_mpOs
./laplacian_filter1_mpn
./laplacian_filter1_mpn1
./laplacian_filter1_mpn2
./laplacian_filter1_mpn3
./laplacian_filter1_mpns
objdump -S -d laplacian_filter1_mp | grep "vmov" -c
objdump -S -d laplacian_filter1_mpO1 | grep "vmov" -c
objdump -S -d laplacian_filter1_mpO2 | grep "vmov" -c
objdump -S -d laplacian_filter1_mpO3 | grep "vmov" -c
objdump -S -d laplacian_filter1_mpOs | grep "vmov" -c
objdump -S -d laplacian_filter1_mpn | grep "vmov" -c
objdump -S -d laplacian_filter1_mpn1 | grep "vmov" -c
objdump -S -d laplacian_filter1_mpn2 | grep "vmov" -c
objdump -S -d laplacian_filter1_mpn3 | grep "vmov" -c
objdump -S -d laplacian_filter1_mpns | grep "vmov" -c

を実行した。
結果を示す。
OpenMP_10_150717.png

ラプラシアンフィルタ処理後の画面はやはり、前回と同じで、最初に........が余計に出ている。
OpenMP_15_150717.jpg


次に、laplacian_filter2.c をOpenMP を使用するように gcc でオプション付けてコンパイルした。以下の様にCソースコードを修正した。
OpenMP_19_150717.png

同様に、2つ目の for ループの前に、

#ifdef _OPENMP
#pragma omp parallel for private(lap_fil_val, a, b, cam_fb_addr, lap_fb_addr)
#endif

を置いた。

このCソースコードを以下のコマンドで、コンパイル、実行、NEON命令の有無を調査した

。gcc -fopenmp laplacian_filter2.c -o laplacian_filter2_mp
gcc -fopenmp -O1 laplacian_filter2.c -o laplacian_filter2_mpO1
gcc -fopenmp -O2 laplacian_filter2.c -o laplacian_filter2_mpO2
gcc -fopenmp -O3 laplacian_filter2.c -o laplacian_filter2_mpO3
gcc -fopenmp -Os laplacian_filter2.c -o laplacian_filter2_mpOs
gcc -fopenmp -mcpu=cortex-a9 -mfpu=neon -ftree-vectorize -mvectorize-with-neon-quad -ffast-math laplacian_filter2.c -o laplacian_filter2_mpn
gcc -fopenmp -mcpu=cortex-a9 -mfpu=neon -ftree-vectorize -mvectorize-with-neon-quad -ffast-math -O1 laplacian_filter2.c -o laplacian_filter2_mpn1
gcc -fopenmp -mcpu=cortex-a9 -mfpu=neon -ftree-vectorize -mvectorize-with-neon-quad -ffast-math -O2 laplacian_filter2.c -o laplacian_filter2_mpn2
gcc -fopenmp -mcpu=cortex-a9 -mfpu=neon -ftree-vectorize -mvectorize-with-neon-quad -ffast-math -O3 laplacian_filter2.c -o laplacian_filter2_mpn3
gcc -fopenmp -mcpu=cortex-a9 -mfpu=neon -ftree-vectorize -mvectorize-with-neon-quad -ffast-math -Os laplacian_filter2.c -o laplacian_filter2_mpns
./laplacian_filter2_mp
./laplacian_filter2_mpO1
./laplacian_filter2_mpO2
./laplacian_filter2_mpO3
./laplacian_filter2_mpOs
./laplacian_filter2_mpn
./laplacian_filter2_mpn1
./laplacian_filter2_mpn2
./laplacian_filter2_mpn3
./laplacian_filter2_mpns
objdump -S -d laplacian_filter2_mp | grep "vmov" -c
objdump -S -d laplacian_filter2_mpO1 | grep "vmov" -c
objdump -S -d laplacian_filter2_mpO2 | grep "vmov" -c
objdump -S -d laplacian_filter2_mpO3 | grep "vmov" -c
objdump -S -d laplacian_filter2_mpOs | grep "vmov" -c
objdump -S -d laplacian_filter2_mpn | grep "vmov" -c
objdump -S -d laplacian_filter2_mpn1 | grep "vmov" -c
objdump -S -d laplacian_filter2_mpn2 | grep "vmov" -c
objdump -S -d laplacian_filter2_mpn3 | grep "vmov" -c
objdump -S -d laplacian_filter2_mpns | grep "vmov" -c

を実行した。
結果を示す。
OpenMP_11_150717.png

ラプラシアンフィルタの画像的には、左側はそれなりだが、右側が強調されている気がする。
OpenMP_16_150717.jpg
  1. 2015年07月17日 05:25 |
  2. Zynq
  3. | トラックバック:0
  4. | コメント:3

コメント

コンパイラが理解しやすい(for文の中で分岐をしない等の)コーディングをしないと、マルチスレッドもうまくいかないのでしょうか。

マルチスレッドが左右2分割で行われていると仮定して、左はmemcpy完了後に実行、右はmemcpy前から実行。
フィルタ1と2の出力の違いはメモリの扱い方の差かな?と予想しました(今回は当たるかな?)

for文の中のmemcpyがうまくなさそうなので、memcpyが終わるのを待ってからスレッドの同期をかける方法があるような気がします。
  1. 2015/07/17(金) 10:41:15 |
  2. URL |
  3. おる #mQop/nM.
  4. [ 編集 ]

#pragma omp parallel for を付けたfor文の中には#pragma omp barrier が付けられなかったです。いろいろと制限があるようです。
とりあえずは結果がどうであれ、実力的にどのくらい出るかを検証しました。
  1. 2015/07/18(土) 04:48:06 |
  2. URL |
  3. marsee #f1oWVgn2
  4. [ 編集 ]

管理人のみ閲覧できます

このコメントは管理人のみ閲覧できます
  1. 2015/07/18(土) 09:10:51 |
  2. |
  3. #
  4. [ 編集 ]

コメントの投稿


管理者にだけ表示を許可する

トラックバック URL
http://marsee101.blog19.fc2.com/tb.php/3201-fc81f552
この記事にトラックバックする(FC2ブログユーザー)