やっとラズパイZeroWが手に入ったのでとりあえずGo言語でGPIOアクセス速度の調査を行った
調査は単純にGPIOをトグルし1Clockの周波数を取得した。
2018/4/29 コメントにてCコンパイラの最適化オプションを使うと良いとのことなのでWiringPi-Goで追加検証
for {
pin.Toggle()
}
調査結果
-
gobot
結果は 10KHzと遅い。デューティも悪い。
だが、このライブラリはI2C、SPI、センサ等の部品をサポートする初心者にやさしいライブラリであり、GitHubスターも多い。oledの動作確認でお世話になったので応援したい
公式のサンプルコードの内容がHelloWorld程度なのが少し残念。
-
go-rpio
結果は400KHz。Cの1/10以下と寂しい結果
-
bcm2835
結果は340KHz。CのBCM2835はWiringPiより速いはずなのになぜそうならないのか・・・bcm2835とかCGOでCをコールしてるだけだと思うのだが、オーバヘッドでかすぎ
-
WiringPi-Go
結果は200KHz。やっぱりオーバヘッドがでかいみたい。
あとソースの修正が必要だった。
WiringPi-Goのソースに最適化オプションを追加して再調査
結果は300KHzと効果あり。ただ、前回のコードを実行すると250KHzだったので効果20%となる。
package rpi
/*
# cgo CFLAGS: -g -O3 -std=c99
# cgo LDFLAGS: -lwiringPi
CGOのオプションについては初めて触ったのでやり方が合っているのかわからないが、
適当に書き換えるとGoコンパイラに怒られるし、結果が変わるので大丈夫だろう・・・
CGOのオプションてコメントで書けるのか
あとがき
GoならCに近い性能がでると思っていたので、Go信者※の俺にはツライ現実だった。まぁラズパイではI2CとSPIが使えればいいよね
※仕事で.Netしかさわらないので、いつまでたってもGoを覚えられないけど、Goの設計思想に感銘を受けた。が普段つかわないので覚えられない
というわけでGoで少しでも速いGPIOが欲しいならgo-rpioを使おう。
ちなみに、ToggleよりHigh/Lowと書いたほうが10%くらい速くなった。
Toggleは切り替え前にif文が入るため速度が落ちるようだ。
for {
pin.High()
pin.Low()
}