画像の二値化を SIMD で高速化する
August 10th, 2010 | Published in CS | 1 Comment
SIMD の練習がてら、 ARM NEON で画像の二値化を SIMD 化してみる。
元コードは、 実践! iPhoneアプリ開発 : カメラアプリの作り方 (4) – 写真にエフェクトをかける で、 RGB から Y に変換するところと、 UIImage とビットマップとをやりとりするところを流用しています。
SIMD 化戦略は、単純なピクセル並列。 RGBA 各1バイトのピクセルを複数ピクセルまとめて処理するだけ。スケーリングとかのアルゴリズムと違って、近傍のピクセルを考慮しなくてよいので、端の処理も気にしないで済む。
RGB は1バイトなんだけれど、 Y に変換する際に 1バイトで表現できる以上の整数値を扱うことになるので、2バイトの整数で計算する。なので8ピクセルの SIMD にしたのが以下のコード:
まぁ分かりやすい。
iPhone 4、 -Os、 2592×1936 な JPG 画像で試したところ、
- naive な実装 : 0.689s
- NEON SIMD : 0.613s
と僅差で勝利した.. 詳しく追ってないけれど、最後のメモリ書き戻しのところが遅そう。
あとはこれを VFP でもやりたいんだけど、ちょっとめんどうげな。最初に RGB を float に変換してしまって、 4並列の SIMD でやることになるかな。果たして naive な実装に勝てるんだろうか.. GCC/Clang こわいです。