ARM アセンブラで YUV422 -> RGB 変換を(未完)

| コメント(0) | トラックバック(0) このエントリーを含むはてなブックマーク

今日は、ARM CPUで出来るだけ計算を沢山行い、 ARM CPU自身の機能をしゃぶりつくすことについて書いてみる。

きっかけ

twitterのつぶやきに、YUV422からRGB565への変換が遅いというのが、この記事を書くきっかけになった。

元のコードは高級言語で書かれているようである。

チューニング案

  • コンパイラの最適化を借りる
    この方法が順当である。ポータビリティも上がり非常に良い。
  • カリカリのアセンブラチューニング
    ふつうはしない。

今回は後者を行ってみる

対象ターゲットはARM

その前に ARM CPU についての詳細は wikipedia 等を参照してもらうとして主な特徴は

  • 32bit RISC CPU
  • 16本の32bit汎用レジスタ
  • 組込み向け/省電力向け用

となり、最近では携帯電話やポータブルゲーム機等にも採用されている。

ALU周り

今回、計算処理について語りたい。計算処理ということでALU周りについて書いておく。

ARMのALUは メインとなるALU 以外に、前段にパラレルシフタを配置している。

 

20091221_ARM.png

 

いきなりではあるが、以下のコードを書いたとする

ADD R0,R1,R2
ADD R3,R4,R5, LSL #2
 
 
  • 最初の命令は R1 と R2 の値を足して R0 に代入
    先ほどの図で示すと、Rn が R0 , Rm と R1 , R2 と Rp と対応する。
    (この時のパラレルシフタは無視してください)
  • 次の命令は R5の値を左に#2ビットシフトして、R4 の値を足して R3 に代入
    先ほどの図で示すと、R5 が Rp と対応しており、# が 2 となる。さらにR4がRmと対応して
    RnがR3と対応する。

これを踏まえると、ある値がR1にありそれを5倍するとき以下の1命令で済む

ADD R1,R1,R1, LSL #2
 
 

R1を左に2ビットシフトして、それをR1と足し、さらにそれを R1 に入れる つまり R1 <- R1 + (R1 << 2) となる。

YUV422からRGBへの変換

変換式

R = 1.000Y          + 1.402V
G = 1.000Y - 0.344U - 0.714V
B = 1.000Y + 1.772U
 
 

以上の変換式が一般的な変換式のようである。

ARMへの対応と最適化

本来だと浮動小数点を用い計算を行うが、最適化の為に以下のように考えてみる。

R = 1.000Y           + 1.5V
G = 1.000Y - 0.375U  - 0.75V
B = 1.000Y + 1.75U 
 
 

変更点は

  • 1.402V を 1.5V へ
  • 0.344U を 0.375U へ
  • 0.714V を 0.75V へ
  • 1.772U を 1.75U へ

この変更を行い、最適化を行っている。

ちなみに

  • 1.5V = (Vx2 + V) / 2 = 3V/2
  • 0.375U = (Ux2+U)/8 = 3U/8
  • 0.75V = (Vx4+Vx2)/8 = 6V/8
  • 1.75U = (Ux4+Ux2)/8 +U = 6U/8 + U

となり、基本的に2のべき乗と足し算、2のべき乗の割り算で出来るようにした。 なお、1.772U を 1.75U は乱暴のような気がする。57/32 = 1.78 という案もあるが、 この場合、57を作るのに(32+16+8+1)のように多項式が増える。

実装

まずは 1.5V を作ってみる 例えば、R6にVがあり、R0に1.5V を代入するとすると

ADD R1,R6,R6,LSL #1
MOV R0,R1,LSR #1
 
 

という2命令になる。なおこの1命令は見かけ上1クロックで動くため、2クロックで変換できる。

もし R7 に Y が入っており、R8にRだとすると

R = 1.000Y           + 1.5V
 
 

ADD R1,R6,R6,LSL #1
MOV R0,R1,LSR #1
ADD R8,R7,R0
 
 

となる。

ここで1つ。

ADD R1,R6,R6,LSL #1
ADD R8,R7,R1,LSR #1
 
 

とすると2命令で済む。 ちなみに、この命令削減は...640x400の画像だと256000命令削減できる。

続き

このような手法でやっていくと最適化されたものができる。 この続きは流石に実機がないとつらい。(SheevaPlug持ってるけど)

さいごに

アセンブラでARM CPU を触りこむ場合、上記の事を踏まえるとより 高速になるかもしれない。

ふつうは、コンパイラの最適化を期待してください。

参考文献

トラックバック(0)

トラックバックURL: http://www.m-tea.info/mt-tb.cgi/48

コメントする

あわせて読みたいブログパーツ

このブログ記事について

このページは、k1ha410が2009年12月21日 23:17に書いたブログ記事です。

ひとつ前のブログ記事は「Google App Engine は PaaS , AzureもPaaS?」です。

次のブログ記事は「2009年FITEA忘年会」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。