fresh digitable

セミコロンたちが躍動する おいらのコードを 皆さんに 見せたいね

頭外音像定位アプリのプロジェクトにandroidx.benchmarkを導入してみた

これです

github.com

androidx.benchmarkは何となく気になっていたので、冬休みの間の宿題として、数年前に作ったあと放置していたリポジトリをほじくり返してこれに導入してみることにした。何をやっているのかは

akihito104.hatenablog.com

にだいたい書いてある。今回はFFTをやっているところと、畳み込み演算をやっているところのベンチマークをとってみることにした。

今回のポイント

公式のドキュメントを参考にしながら、benchmarkモジュールを追加するやつをやった。

developer.android.com

これ以外に、今回のプロジェクトで必要だった作業は次の二つ:

  • サポートライブラリを使っていたのだが、benchmarkはandroidxのライブラリなのでjetifyした。
  • シングルモジュールの構成になっていたのだが、benchmarkモジュールはlibraryモジュールなのでapplicationモジュールのプロジェクトに依存できない。ベンチマークをとりたいコードを別のモジュールに移した。

また、ドキュメントには./gradlew benchmark:connectedCheckをやるとプロジェクトのoutputフォルダに測定結果ファイルがコピーされると書いてあるが、ver. 1.0.0ではコピーするタスク(benchmark:benchmarkReport)で失敗する*1。結果ファイル自体は端末の外部ストレージに保存されているので自分でpullすればよい。

ベンチマークの測定結果と考察

ベンチマークの測定結果ファイルには、かかった時間の最大値、最小値、中央値、各イテレーションの実測値などが書いてある。また、ウォームアップの回数なんかもわかる。実際のファイルは上のPRに張り付けたので興味のある方は実際に見てみてほしい。

これによると、畳み込み演算の実行時間の中央値はFFTのものと比べて8倍程度になっている。想定では畳み込み演算の中でFFTは6回しかやっていないはずだし、なんなら内部的には畳み込み演算を並列に計算したりしているのだが、複素数の乗算や加算、スレッドの待ち合わせなどの分でFFTを2回余計にやるぐらいの時間がかかってしまっているというのがわかる。

もう少し詳しく見ていく必要はありそう*2だが、確かにFFTや畳み込み結果の待ち合わせ処理には改善の余地がありそうなので、アルゴリズムを見直したり、Kotlinのコルーチンを入れたりして様子を見ていきたい。

*1:何が原因なのかは洗い切れていない。

*2:FFT自体の性能とかどの計算にどれだけ使っているのかなど