サンプル:GUIを用いたCUDAプログラム
続いて、GUIを用いたサンプルプログラム「nbody」を実行してみます。nbodyはCUDAで記述された多体問題のシミュレーションプログラムです。
実行は次のコマンドで行います。nbodyを終了するには[Esc]キーを押します。
cd $HOME/NVIDIA_CUDA-6.5_Samples/5_Simulations/nbody ./nbody
cd $HOME/NVIDIA_CUDA-6.5_Samples/5_Simulations/nbody ./nbody
nbodyプログラムは、./nobody -benchmark を実行することでベンチマークを行うことができます。
1024 bodies, total time for 10 iterations: 1.477 ms = 7.101 billion interactions per second = 142.019 single-precision GFLOP/s at 20 flops per interaction
上記は単精度(single-precision)浮動小数点数で計算した場合のベンチマークなのですが、倍精度(double-precision)浮動小数点数で計算した場合のベンチマークを行うこともできます。
./nbody -fp64 -benchmark 1024 bodies, total time for 10 iterations: 28.974 ms = 0.362 billion interactions per second = 10.857 double-precision GFLOP/s at 30 flops per interaction
性能は「billion interactions per second」の値に現れます。比較すると、倍精度での性能は、単精度での性能の約20分の1(7.101:0.362)という結果になりました。
理由は、GK104をベースとしているTegra K1(GK20a)は、Keplerアーキテクチャですが倍精度の浮動小数点数計算ユニットを搭載していないためです。とはいえ、通常は24分の1になるといわれているので、想定していたよりも良い結果になりました(参考:PC Watch記事「NVIDIAが究極のモバイルSoC「Tegra K1」を発表」)。
また、GPUではなく、CPUでnbodyを計算した場合のベンチマークを行うこともできます(上が単精度浮動小数点数、下が倍精度浮動小数点数で計算した場合の結果)。
./nbody -numbodies=1024 -cpu -benchmark 1024 bodies, total time for 10 iterations: 2642.112 ms = 0.004 billion interactions per second = 0.079 single-precision GFLOP/s at 20 flops per interaction
./nbody -numbodies=1024 -fp64 -cpu -benchmark 1024 bodies, total time for 10 iterations: 2690.587 ms = 0.004 billion interactions per second = 0.117 double-precision GFLOP/s at 30 flops per interaction
結果を見ると、CPUでは単精度と倍精度の性能は同じ(0.004:0.004)でした。
サンプル:OpenCVで歩行者を検知するプログラム
今度はOpenCVを使って、動画から歩行者を検知するサンプルプログラム「Hog」を動かしてみましょう。Hogは別途入手する必要があります。次のコマンドで、サンプルプログラムを含んでいる「OpenCV2.4.9」をダウンロードし、解凍してください。
cd $HOME wget http://downloads.sourceforge.net/project/opencvlibrary/opencv-unix/2.4.9/opencv-2.4.9.zip unzip opencv-2.4.9.zip
解答したら、サンプルプログラムが入っているディレクトリに移動し、プログラム「hog.cpp」をコンパイルします。
cd opencv-2.4.9/samples/gpu g++ hog.cpp -lopencv_core -lopencv_imgproc -lopencv_highgui -lopencv_calib3d -lopencv_contrib -lopencv_features2d -lopencv_flann -lopencv_gpu -lopencv_legacy -lopencv_ml -lopencv_objdetect -lopencv_photo -lopencv_stitching -lopencv_superres -lopencv_video -lopencv_videostab -o hog
コンパイルができたら、Hogを実行してみましょう。video オプションを付けてavi形式の動画ファイルを読み込み、歩行者検知を行ってみます。
./hog --video 768x576.avi
実行すると、次のような出力がターミナルに表示され、ウィンドウがポップアップします。
ubuntu@tegra-ubuntu:~/opencv-2.4.9/samples/gpu$ ./hog --video 768x576.avi
Device 0: "GK20A" 1743Mb, sm_32, Driver/Runtime ver.6.50/6.50
Controls:
ESC - exit
m - change mode GPU <-> CPU
g - convert image to gray or not
1/q - increase/decrease HOG scale
2/w - increase/decrease levels count
3/e - increase/decrease HOG group threshold
4/r - increase/decrease hit threshold
Scale: 1.05
Group threshold: 8
Levels number: 13
Win width: 48
Win stride: (8, 8)
Hit threshold: 1.4
Gamma correction: 1
ポップアップしたウィンドウには、歩行者と検知している領域に緑色の枠が表示されます。
Hogは、USBカメラから直接動画を取り込んで歩行者を検知することもできます(こちらのほうがおもしろいです!)。USBカメラから動画を取り込む場合には、次のコマンドでUSBのauto-offをオフに設定します。
sudo bash -c 'echo -1 > /sys/module/usbcore/parameters/autosuspend'
この設定を永続的にするには、/etc/rc.localファイルに同様の内容を記述します。
sudo sed -i "12a echo -1 > /sys/module/usbcore/parameters/autosuspend" /etc/rc.local
USBカメラを使って歩行者検知を行うには、camera オプションを付けてHogを実行します。歩行者として検知されるためには、人物がカメラから数メートル離れる必要があります。
./hog --camera 0

