中田真秀(なかたまほ)のブログ

研究について、日常について、その他。

OpenBLAS 測定 sgemm slinpack saxpy dgemm dlinpack daxpy on Raspberry Pi2

2016-03-31 12:59:34 | 日記
OpenBLAS-0.2.17をビルド。

Swapを加える。ないとメモリ使い果たして固まる。
$ make FC=gfortran
$ sudo dd if=/dev/zero of=/swap bs=1M count=2048
$ sudo chmod 600 /swap
$ sudo mkswap /swap
$ sudo swapon /swap
$ sudo apt-get install gfortran

展開

$ tar xvfz OpenBLAS-0.2.17.tar.gz

patchあて(ほとんど無意味)

--- Makefile.arm~ 2016-03-21 09:52:15.000000000 +0900
+++ Makefile.arm 2016-03-31 11:47:16.822314531 +0900
@@ -14,8 +14,8 @@
CCOMMON_OPT += -marm -mfpu=neon -mfloat-abi=hard -march=armv7-a -Wl,--no-warn-mismatch
FCOMMON_OPT += -marm -mfpu=neon -mfloat-abi=hard -march=armv7-a -Wl,--no-warn-mismatch
else
-CCOMMON_OPT += -marm -mfpu=vfpv3 -mfloat-abi=hard -march=armv7-a
-FCOMMON_OPT += -marm -mfpu=vfpv3 -mfloat-abi=hard -march=armv7-a
+CCOMMON_OPT += -marm -mfpu=vfpv4 -mfpu=neon -mfloat-abi=hard -march=armv7-a
+FCOMMON_OPT += -marm -mfpu=vfpv4 -mfpu=neon -mfloat-abi=hard -march=armv7-a
endif
endif


ビルド

$ make FC=gfortran
$ cd benchmark ; make

(適宜固まるので電源抜き差しなど対応すること)

測定

$ ./sgemm.goto 1500 2000
From : 1500 To : 2000 Step=1 : Trans=N
SIZE Flops Time
1500x1500 : 4461.05 MFlops 1.513098 sec
1501x1501 : 4474.39 MFlops 1.511606 sec
1502x1502 : 4462.28 MFlops 1.518739 sec
1503x1503 : 4474.17 MFlops 1.517730 sec
1504x1504 : 4500.73 MFlops 1.511786 sec
1505x1505 : 4462.66 MFlops 1.527727 sec
1506x1506 : 4497.68 MFlops 1.518854 sec


$ ./slinpack.goto 1500 2000
From : 1500 To : 2000 Step = 1
SIZE Residual Decompose Solve Total
1500 : 5.394816e-04 3558.81 MFlops 161.34 MFlops 3415.26 MFlops
1501 : 2.735615e-03 3558.99 MFlops 163.17 MFlops 3417.14 MFlops
1502 : 2.254963e-03 3551.39 MFlops 166.34 MFlops 3412.94 MFlops
1503 : 9.852052e-04 3545.54 MFlops 163.44 MFlops 3405.17 MFlops
1504 : 5.353689e-04 3541.81 MFlops 163.39 MFlops 3401.78 MFlops
1505 : 5.227327e-04 3551.44 MFlops 173.23 MFlops 3418.80 MFlops
1506 : 5.793571e-04 3576.60 MFlops 186.54 MFlops 3451.88 MFlops


From : 10000 To : 200000 Step = 100 Inc_x = 1 Inc_y = 1 Loops = 1
SIZE Flops
10000 : 222.22 MFlops
10100 : 651.61 MFlops
10200 : 755.56 MFlops
10300 : 710.34 MFlops
10400 : 832.00 MFlops
10500 : 724.14 MFlops
10600 : 815.38 MFlops
10700 : 737.93 MFlops
10800 : 800.00 MFlops
10900 : 751.72 MFlops
11000 : 785.71 MFlops
11100 : 765.52 MFlops
11200 : 800.00 MFlops
...
91400 : 520.80 MFlops
91500 : 539.82 MFlops
91600 : 483.38 MFlops
91700 : 536.26 MFlops
91800 : 514.29 MFlops
91900 : 543.79 MFlops

800MFlops超えたら500MFlopsまでだんだん遅くなった

$ ./dgemm.goto 1000 1500 10
From : 1000 To : 1500 Step=10 : Trans=N
SIZE Flops Time
1000x1000 : 1794.16 MFlops 1.114725 sec
1010x1010 : 1808.33 MFlops 1.139505 sec
1020x1020 : 1793.40 MFlops 1.183461 sec
1030x1030 : 1818.51 MFlops 1.201786 sec
1040x1040 : 1817.89 MFlops 1.237546 sec
1050x1050 : 1820.19 MFlops 1.271981 sec
1060x1060 : 1829.72 MFlops 1.301855 sec
1070x1070 : 1819.74 MFlops 1.346393 sec
1080x1080 : 1806.13 MFlops 1.394932 sec
1090x1090 : 1837.65 MFlops 1.409439 sec
1100x1100 : 1817.40 MFlops 1.464730 sec

倍精度1.8GFlopsとなって若干良くなった。
たぶんvfpv4のみ使ってるっぽい。

$ ./dlinpack.goto 1000 1500 10
From : 1000 To : 1500 Step = 10
SIZE Residual Decompose Solve Total
1000 : 8.907319e-13 1512.48 MFlops 85.28 MFlops 1440.38 MFlops
1010 : 2.419398e-12 1536.27 MFlops 89.57 MFlops 1466.14 MFlops
1020 : 5.098300e-11 1529.05 MFlops 91.08 MFlops 1461.39 MFlops
1030 : 9.028334e-13 1531.56 MFlops 90.00 MFlops 1463.48 MFlops
1040 : 1.335487e-12 1541.49 MFlops 86.17 MFlops 1470.07 MFlops
1050 : 6.100676e-13 1547.97 MFlops 88.97 MFlops 1478.87 MFlops
1060 : 1.242562e-12 1551.80 MFlops 90.47 MFlops 1484.14 MFlops
1070 : 1.787015e-12 1561.29 MFlops 88.33 MFlops 1491.74 MFlops



From : 10000 To : 200000 Step = 100 Inc_x = 1 Inc_y = 1 Loops = 1
SIZE Flops
10000 : 139.86 MFlops
10100 : 492.68 MFlops
10200 : 523.08 MFlops
10300 : 528.21 MFlops
10400 : 547.37 MFlops
10500 : 552.63 MFlops
10600 : 557.89 MFlops
10700 : 548.72 MFlops
10800 : 553.85 MFlops
10900 : 545.00 MFlops
11000 : 550.00 MFlops
11100 : 555.00 MFlops
11200 : 560.00 MFlops
11300 : 538.10 MFlops
11400 : 570.00 MFlops
11500 : 560.98 MFlops
11600 : 565.85 MFlops
11700 : 557.14 MFlops
...
87700 : 166.73 MFlops
87800 : 168.20 MFlops
87900 : 168.07 MFlops
88000 : 187.63 MFlops
88100 : 163.75 MFlops


ソースを見ると、kernel/arm/KERNEL.ARMV7が使われてることで、vfpしか使ってない。vfpv4か3かは違いがわからん
あとNEONは使ってません...ということがわかった。
https://community.arm.com/groups/android-community/blog/2015/03/27/arm-neon-programming-quick-reference
によるとARMv7-A NEONはdoubleはサポートされてない。

まとめ

  • OpenBLASはvfpに対応していてそこそこ高速。倍精度では多分限界近い1.8GFlopsを出す。
  • gemmはvfpのソースしかないので、多分上のパッチはgcc, gfortranでコンパイルされるところのみ意味があると思われる。
  • 単精度もvfpにのみ対応。NEONに対応させると更に7.2GFlops出せる。さらにVideoCore IVだと24GFlops出せるはず。ということで、4+7+24=35GFlopsが限界??ちょいわかりませんが。
  • Swapは足すこと。足してもめもりたりなさそうなところはある。

Raspberry Pi2で行列行列積: 単精度3.4GFlops

2016-03-31 11:37:42 | 日記
昨日は倍精度だったのだが今日は単精度ということで
octave:1> n=2000 ; A=rand(n); B=rand(n);
octave:2> sA=single(A); sB=single(B);
octave:3> tic();sC=sA*sB;t=toc(); GFLOPS=2*n^3/t*1e-9
GFLOPS =  1.3043
octave:4> tic();sC=sA*sB;t=toc(); GFLOPS=2*n^3/t*1e-9
GFLOPS =  3.3006
octave:5> tic();sC=sA*sB;t=toc(); GFLOPS=2*n^3/t*1e-9
GFLOPS =  3.4351
octave:6>

と結構悪い結果が出てしまった。
peakは8GFlops(7.2GFlops)のはずであるが...

Raspberry Pi2で行列行列積: 1.55GFlops

2016-03-30 14:04:42 | 日記
Raspberry Pi2でも数値計算がやりたいとなると、基本的なライブラリであるBLASが必要となる場合が多い。そしてこいつは最適化の有無で全くパフォーマンスが違う。Raspbianではどうか調査してみた


apt-getでインストールしてみる。
$ sudo apt-get -y install libopenblas-dev libopenblas-base
...
$ sudo apt-get -y install octave
...

さくっと入った。
次に、

$ sudo update-alternatives --config libblas.so.3
There are 3 choices for the alternative libblas.so.3 (providing /usr/lib/libblas.so.3).

Selection Path Priority Status
------------------------------------------------------------
* 0 /usr/lib/openblas-base/libblas.so.3 40 auto mode
1 /usr/lib/atlas-base/atlas/libblas.so.3 35 manual mode
2 /usr/lib/libblas/libblas.so.3 10 manual mode
3 /usr/lib/openblas-base/libblas.so.3 40 manual mode

Press enter to keep the current choice[*], or type selection number:

となってることを確認しOCTAVEで行列行列積の計算をしてみる。

octave:1> n=1000 ; A=rand(n); B=rand(n);
octave:2> tic();C=A*B;t=toc(); GFLOPS=2*n^3/t*1e-9
GFLOPS = 0.97428
octave:3> tic();C=A*B;t=toc(); GFLOPS=2*n^3/t*1e-9
GFLOPS = 1.5421
octave:4> tic();C=A*B;t=toc(); GFLOPS=2*n^3/t*1e-9
GFLOPS = 1.5506
octave:5> quit


最初のは、CPUのクロックが低いため(/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq をcatせよ)。次にあったまってきたCPUは1GHzにオーバークロックしてるためか1.55GFlopsくらい出た。


なお、参照BLASでは、0.09GFlops

octave:1> n=1000 ; A=rand(n); B=rand(n);
octave:2> tic();C=A*B;t=toc(); GFLOPS=2*n^3/t*1e-9
GFLOPS = 0.088390
octave:3> tic();C=A*B;t=toc(); GFLOPS=2*n^3/t*1e-9
GFLOPS = 0.088270


ATLASでは、0.18GFlops

octave:1> n=1000 ; A=rand(n); B=rand(n);
octave:2> tic();C=A*B;t=toc(); GFLOPS=2*n^3/t*1e-9
GFLOPS = 0.18339
octave:3> tic();C=A*B;t=toc(); GFLOPS=2*n^3/t*1e-9
GFLOPS = 0.18341

ATLASではDebianのパッケージはマルチコア使わない。ただ、もし使ったとしても0.72GFlops(=0.18x4)程度と、OpenBLASが二倍くらい高速。

これまでの文献と比較として
http://web.eece.maine.edu/~vweaver/group/green_machines.html
からは、
1.47 GFLOPS
となっていたので、こんなものだと思われる。

ちなみに単精度でよければ、GPUであるVideoCoreIVを使うのも良いかもしれない。
http://qiita.com/9_ties/items/2e85318989170f967e4b
24GFlops位出るらしい...
さらに、単精度だとCPUを併用することで
http://dench.flatlib.jp/opengl/cpuflops
7.2 GFLOPS余計に出せるはず。
30GFlops超えられるか、かね。
ただし単精度という感じか。

理論ピーク性能を考える。
http://dench.flatlib.jp/opengl/cpufop madが0.5 fmaが0.4
http://dench.flatlib.jp/opengl/cpuflops の内容を信じるとすると、
RaspberryPi2のCortex A7は900MHz浮動小数点演算はVFPv4 + NEONの2つの構成。
NEONだけだと
NEON: 0.5(mad) x1(simd) x4(core) x0.9(clock) = 1.8 GFLOPS (上記結果は理論ピーク性能の82%)
NEON: 0.5(mad) x1(simd) x4(core) x1.0(clock) = 2.0 GFLOPS (上記結果は理論ピーク性能の78%)
となっている。
たぶんOpenBLASはMADで計算してるのだろうな。VFPv4は同時に使えるのかは知らない。

Raspberry Pi 2でHDMI 720pをキャプチャする

2016-03-28 16:28:59 | 日記
HDMI 720pをRaspberry Pi 2でキャプチャしてみた

HDMIのキャプチャについてはいろんな人が欲している割には実現されておらず、結構しょっぱい。フォーラム見てもできそうなことが書かれているが情報が散漫であって非常にわかりづらい。日本語であるが
IMRCさんのRaspberry Pi (Trading) Ltd.のHDMI入力ボードと外付けディスプレイの試作品についての調査が大変よくまとまっている(まとめる手間が省けた)。

いろいろ途上っぽい+偶然的な要素もあるのだが、auvidiaからB101 HDMI to CSI-2 Bridge (15 pin FPC)なる製品が出ている。CSI-2ブリッジを通してキャプチャできるらしい。ほんまかいなと思って買ってみた。

で、やってみたらできました。まずはカメラが使えるのが前提で、それには

copyright (C) 2013-2015 Jun Mizutani
Raspberry Pi のカメラモジュールの使い方 (2013/07/26, 2013/12/01)
とかを見ればなんとかなる。
Enable cameraとしてリブートする。
その後、
$ sudo chmod a+rw /dev/vchiq
$ raspivid -o video.h264 -t 100000 -d

とすれば問題なく録画出来ていた。

だだ流し。ネットワーク越しに見るとすると
ラズベリーパイ側

$ raspivid -t 0 -w 1280 -h 720 -fps 30 -o - | nc -k -l -p 2222

ホスト側

$ mplayer -fps 200 -demuxer h264es ffmpeg://tcp://172.27.42.54:2222

とすると、ホスト側でHDMIのキャプチャをリアルタイムで流せる。

なお、現物の写真もあげておく


お疲れ様でした。

Raspberry Piで監視カメラ作成。一万円程度。

2016-03-17 12:29:43 | 日記
Raspberry Pi+MotionEyeOSで監視カメラを作ってみた。ドライブレコーダーなどに応用できたらいいなと思っている。
ただ、なんとなく作っていると色んな物を買わなくてはならず、意外とアレも必要、これも必要となってしまう

若干まとめてみた。

特徴
* ラズベリーパイを用いており、パソコンでできそうなことはなんでも可能。
* 複数台カメラ接続可能。
* モーション発生時に録画する機能あり。
* webインターフェースでスマホなどからストリーミングで見られる。設定もwebインターフェースで可能
* Dropboxで動画を同期できる。そのためSDカード損傷の場合などデータ保全に有利。
* メールなどでイベント事に情報送信可能。

ハードで必要なもの
* Raspberry Pi (2, 3でなくとも良い) 3500円 (RS online)
* ケース 2000円
* web camera 2000円(上はきりがない) Linux対応を確認すること
* SDカード 16GB 1000円
* Wifiドングル 1000円
* 電源ケーブル 100円
* その他、あると便利なもの。HDMIケーブル、イーサネットケーブル、キーボード、マウス

合計すると一万円程度となる。

ソフトで必要なもの
* MotionEyeOS https://github.com/ccrisan/motioneyeos/wiki/Installation

OSをSDカードに書き込んでサクッとインストール完了。
* パスワードを設定。
* preferenceで設定。

こんな感じ。普通に買うと2万くらいかな
みなさんのご参考になれば。