2018年11月11日日曜日

Raspberry PiのGPUをOpenCLで使う方法


背景

Raspberry Piとは、1000円から6000円で買える、Linuxが動くコンピュータです。
そのRaspberry PiにはVideo Cove IVというGPUが載っています。
VC4CLというプロジェクトを利用すると、並列処理ライブラリであるOpenCVでRaspberry PiのGPUを利用できるようになります。

どのような性能なのか気になったので、VC4CLを通してRaspberry PiのGPUをOpenCLで利用する方法を共有します。

使ったもの

  • Raspberry Pi
    Zero Wで動くことを確認しました。
  • Raspbian
    2018年10月にリリースされたLite版を利用しました。
    ビルドの依存関係を満たすために、stretch以上のRaspbianが必要です。
    OSのバージョンは下記のコマンドで確認できます。
    lsb_release -a
    自分の環境では下記のように表示され、stretchであることを確認できました。
    No LSB modules are available.
    Distributor ID: Raspbian
    Description: Raspbian GNU/Linux 9.4 (stretch)
    Release: 9.4
    Codename: stretch
    

VC4CLをインストール

Wikiのを参考に、パッケージをダウンロードしてインストールします。
自分が試したときは、下記のコマンドが指示されていました。
インストールできないときは、 How to getで最新のコマンドを確認してください。
cd /tmp
wget https://raw.githubusercontent.com/doe300/VC4CL/master/.circleci/get_url.py
wget https://raw.githubusercontent.com/doe300/VC4CL/master/.circleci/build_num.py
curl "https://circleci.com/api/v1.1/project/github/doe300/VC4C" --output /tmp/json
curl "https://circleci.com/api/v1.1/project/github/doe300/VC4C/$(python ./build_num.py /tmp/json)/artifacts" --output /tmp/dump
wget -O /tmp/vc4cl-stdlib.deb $(python get_url.py "vc4cl-stdlib-" "/tmp/dump")
wget -O /tmp/vc4c.deb $(python get_url.py "vc4c-" "/tmp/dump")
curl "https://circleci.com/api/v1.1/project/github/doe300/VC4CL/latest/artifacts?branch=master&filter=successful" --output /tmp/dump
wget -O /tmp/vc4cl.deb $(python get_url.py "vc4cl-" "/tmp/dump")
sudo dpkg -i /tmp/vc4cl-stdlib.deb
sudo dpkg -i /tmp/vc4c.deb
sudo dpkg -i /tmp/vc4cl.deb
sudo apt --fix-broken install

動作確認

clinfoでの確認

clinfoというプログラムを利用して、VideoCoreVIがOpenCLから見れるようになっているか確認できます。
sudo apt install clinfo
sudo clinfo

認識されているようでした。
Number of platforms                               1
  Platform Name                                   OpenCL for the Raspberry Pi VideoCore IV GPU
  Platform Vendor                                 doe300
  Platform Version                                OpenCL 1.2 VC4CL 0.4
  Platform Profile                                EMBEDDED_PROFILE
  Platform Extensions                             cl_khr_il_program cl_khr_spir cl_altera_device_temperature cl_altera_live_object_tracking cl_khr_icd cl_vc4cl_performance_counters
  Platform Extensions function suffix             VC4CL

行列演算

OpenCLで行列の掛け算をしてみた」で作ったOpenCLのプログラムを実行してみます。
VC4CLは管理者権限でしか扱えないメモリを利用するため、sudoで実行します。
mkdir ~/gitprojects
cd ~/gitprojects
sudo apt install git -y
git clone https://github.com/asukiaaa/c_opencl_practice.git
cd c_opencl_practice
gcc matrix_dot_matrix.c -lOpenCL
sudo ./a.out

実行できました、
sudo ./a.out
matrix
   0.00  10.00  20.00  30.00  40.00  50.00  60.00  70.00  80.00  90.00
   1.00  11.00  21.00  31.00  41.00  51.00  61.00  71.00  81.00  91.00
   2.00  12.00  22.00  32.00  42.00  52.00  62.00  72.00  82.00  92.00
   3.00  13.00  23.00  33.00  43.00  53.00  63.00  73.00  83.00  93.00
   4.00  14.00  24.00  34.00  44.00  54.00  64.00  74.00  84.00  94.00
   5.00  15.00  25.00  35.00  45.00  55.00  65.00  75.00  85.00  95.00
   6.00  16.00  26.00  36.00  46.00  56.00  66.00  76.00  86.00  96.00
   7.00  17.00  27.00  37.00  47.00  57.00  67.00  77.00  87.00  97.00
   8.00  18.00  28.00  38.00  48.00  58.00  68.00  78.00  88.00  98.00
   9.00  19.00  29.00  39.00  49.00  59.00  69.00  79.00  89.00  99.00
matrix
   1.00   0.00   0.00   0.00   0.00   0.00   0.00   0.00   0.00   0.00
   0.00   2.00   0.00   0.00   0.00   0.00   0.00   0.00   0.00   0.00
   0.00   0.00   1.00   0.00   0.00   0.00   0.00   0.00   0.00   0.00
   0.00   0.00   0.00   1.00   0.00   0.00   0.00   0.00   0.00   0.00
   0.00   0.00   0.00   0.00   1.00   0.00   0.00   0.00   0.00   0.00
   0.00   0.00   0.00   0.00   0.00   1.00   0.00   0.00   0.00   0.00
   0.00   0.00   0.00   0.00   0.00   0.00   1.00   0.00   0.00   0.00
   0.00   0.00   0.00   0.00   0.00   0.00   0.00   1.00   0.00   0.00
   0.00   0.00   0.00   0.00   0.00   0.00   0.00   0.00   1.00   0.00
   0.00   0.00   0.00   0.00   0.00   0.00   0.00   0.00   0.00   1.00
CL_DEVICE_MAX_WORK_GROUP_SIZE: 12
work item sizes:  12 12 12
localWorkSize: 10, 1
matrix
   0.00  20.00  20.00  30.00  40.00  50.00  60.00  70.00  80.00  90.00
   1.00  22.00  21.00  31.00  41.00  51.00  61.00  71.00  81.00  91.00
   2.00  24.00  22.00  32.00  42.00  52.00  62.00  72.00  82.00  92.00
   3.00  26.00  23.00  33.00  43.00  53.00  63.00  73.00  83.00  93.00
   4.00  28.00  24.00  34.00  44.00  54.00  64.00  74.00  84.00  94.00
   5.00  30.00  25.00  35.00  45.00  55.00  65.00  75.00  85.00  95.00
   6.00  32.00  26.00  36.00  46.00  56.00  66.00  76.00  86.00  96.00
   7.00  34.00  27.00  37.00  47.00  57.00  67.00  77.00  87.00  97.00
   8.00  36.00  28.00  38.00  48.00  58.00  68.00  78.00  88.00  98.00
   9.00  38.00  29.00  39.00  49.00  59.00  69.00  79.00  89.00  99.00
Load device time: 0.202167 sec
Set kernel time: 3.297173 sec
Set memory time: 0.001143 sec
Set work size time: 0.000406 sec
Calc time: 0.001684 sec
Release resource time: 0.000930 sec
Total time: 3.503503 sec

なお、WikiのLimitationによると、VC4CLはdouble, half, longはサポートしていないようなので、それらの型を扱うときは注意が必要そうです。

Rustで画像処理

 「Rustでステレオ画像のブロックマッチングをしてみた」で作った、Rustというプログラミング言語でOpenCLを利用する画像処理プログラムを実行してみます。
RustのインストールはInstall Rustを参考にしてください。
下記コマンド初回実行時はRustのライブラリのダウンロードやビルドに合わせて1時間くらいかかります。
cd ~/gitprojects
git clone https://github.com/asukiaaa/rust_opencl_block_matching_practice
cd rust_opencl_block_matching_practice/2dims_work_size_with_loop_in_kernel
cargo build
sudo target/debug/2dims_work_size_with_loop_in_kernel

実行してできたファイルはscpなどで自分のPCに転送して確認できます。
Ubuntuの場合はeogコマンドで画像のプレビューを確認できます。
# 自分のPCのターミナルで実行します。
scp pi@[使っているRaspberry PiのIP]:~/gitprojects/rust_opencl_block_matching_practice/2dims_work_size_with_loop_in_kernel/result.png /tmp/
eog /tmp/result.png


Intel GPU + Ubuntuで実行したときと同じ画像が確認できたので、期待通りにGPUを扱えているようです。

CUPと実行時間を比較

Raspberry PiのCPUと比較してOpenCLでGPUを使ったときの処理速度はどうなるのか比較してみました。

使ったRaspberry Pi : Raspberry Pi Zero W
使ったRaspbian: 2018.10リリース版のRaspbian Lite
利用したプログラム: 「OpenCLで行列の掛け算をしてみた」で作成した matrix_dot_matrix.c matrix_dot_matrix_on_cpu.c

動作結果
pi@asukipi0w:~/gitprojects/c_opencl_practice $ gcc matrix_dot_matrix.c -lOpenCL -o gpu
pi@asukipi0w:~/gitprojects/c_opencl_practice $ gcc matrix_dot_matrix_on_cpu.c -o cpu

pi@asukipi0w:~/gitprojects/c_opencl_practice $ sudo ./gpu 128
CL_DEVICE_MAX_WORK_GROUP_SIZE: 12
work item sizes:  12 12 12                              
localWorkSize: 8, 1          
Set matrix time: 0.002697 sec
Load device time: 0.201289 sec
Set kernel time: 3.226910 sec                                
Set memory time: 0.002296 sec    
Set work size time: 0.000486 sec
Calc time: 0.263578 sec
Release resource time: 0.001011 sec
Total time: 3.698267 sec

pi@asukipi0w:~/gitprojects/c_opencl_practice $ ./cpu 128
Set matrix time: 0.002651 sec
Calc time: 0.270916 sec         
Total time: 0.273567 seconds

pi@asukipi0w:~/gitprojects/c_opencl_practice $ sudo ./gpu 512
CL_DEVICE_MAX_WORK_GROUP_SIZE: 12
work item sizes:  12 12 12
localWorkSize: 8, 1
Set matrix time: 0.056850 sec
Load device time: 0.196060 sec
Set kernel time: 3.234914 sec
Set memory time: 0.014732 sec
Set work size time: 0.000425 sec
Calc time: 17.880513 sec
Release resource time: 0.001181 sec
Total time: 21.384675 sec

pi@asukipi0w:~/gitprojects/c_opencl_practice $ ./cpu 512
Set matrix time: 0.055987 sec
Calc time: 37.175322 sec
Total time: 37.231309 seconds

pi@asukipi0w:~/gitprojects/c_opencl_practice $ sudo ./gpu 1024
CL_DEVICE_MAX_WORK_GROUP_SIZE: 12
work item sizes:  12 12 12
localWorkSize: 8, 1
Set matrix time: 0.320146 sec
Load device time: 0.197772 sec
Set kernel time: 3.208944 sec
Set memory time: 0.059525 sec
Set work size time: 0.000492 sec
Calc time: 143.348330 sec
Release resource time: 0.001537 sec
Total time: 147.136746 sec

pi@asukipi0w:~/gitprojects/c_opencl_practice $ ./cpu 1024
Set matrix time: 0.318386 sec
Calc time: 360.395601 sec
Total time: 360.713987 seconds

計算した行列の大きさと実行時間をまとめるとこうなりました。
演算器 行列演算時間(秒)
128x128 512x512 1024x1024
CPU 0.273567 37.231309 360.713987
GPU 3.698267 21.384675 147.136746

計算量の多い処理を上手く並列化できたら、GPUの方がCPUより速くなるようでした。

まとめ

VC4CLを利用することでOpenCLのプログラムをRaspberry Piで動かせました。

何かの参考になれば嬉しいです。

参考

doe300/VC4CL

変更履歴

2019.02.12
Rustのインストール方法に関する情報が不足していたため、関連ページへのリンクを追加しました。
2019.07.13
Raspberry Pi3ならGPUよりCPUの方が早いという説明をしていましたが、未検証なので削除しました。

0 件のコメント :

コメントを投稿