MENU閉じる

LAB

プログラムTIPS最適化Tips

研究室プログラムTIPS2008.8.22

分岐しないコード part2

今回もコーディングテクニックを紹介してみたいと思います。
以前分岐しないコードについて書いてみましたが、今回も別のシチュエーションでの
お話をしてみたいと思います。

たとえば次のようなif文のCプログラムがあったとします。

if( a < b ) {
c = a;
} else {
c = b;
}

これをx86系の通常のアセンブルコードで書くと次のようになります。

    mov    eax, [a]
mov    ebx, [b]
cmp    eax, ebx
jge    l1      // 分岐
l0:<br />
mov    ecx, eax
jmp    l2      // 分岐
l1:<br />
mov    ecx, ebx
l2:
mov    [c], ecx

ここから分岐を一回無くすこともできますが、現状では2回とします。
動きを図で表すとこのような具合ですね。

flow_ifthenelse.gif

そして下記のコードが分岐を無くした最適化コードです。

    mov    eax, [a]
mov    ebx, [b]
cmp     eax, ebx
<br />
sbb    ecx, ecx
// &uarr;ここで0xffffffff または 0x00000000のマスクが生成できる
<br />
and    eax, ecx   // eax = a &amp; mask
not    ecx<br />
and    ebx, ecx   // ebx = b &amp; ~mask
or    ebx, eax   // ebx = (a &amp; mask) | (b &amp; ~mask)

mov    [c], ebx

マスクを生成してそれによって選択する方法です。
最近ではこういった選択実行をするものや
数値入れ替えを行なう命令がCPUに搭載されていることが多いですから、
さらに良い実行コードを出力できることになります。
多少コードが長くなっても分岐しないコードは安定して
コードが実行されるため高速実行できることが多いです。
もとの分岐するコードと比べて何倍・何十倍も実行速度が
速くなる場合があります。CPUが命令を解読する事前デコード
事前実行が行われやすくなります。
稀に処理内容によっては命令数の増加よりも分岐予測や
並列実行が影響して分岐したほうが速いこともあります。
それぞれケース・バイ・ケースですね。

最新のCPUトレンドを追う一方でプログラマもそれに合わせた
プログラミングが求められています。
C言語など高級言語が一般的になった最近でも自らの最終兵器として
アセンブラ技法を習得しておくことは無駄ではありません。
プログラミング技術を磨くために挑戦してみませんか?

ゲームプログラミングの世界では最後の切り札とされる
アセンブラプログラミング!
やってみるとパズルのようでまた違った世界があります。

大量に表示したいときや大量に動かしたい場合にこういった
高速化技法が活きてきます。プログラマの努力によって可能性は
広がります。このような細かい技法をたくさん持っておくことで
いざというときに役立ちます。

今後はリアルタイムレンダリングやAIなど時折紹介できたらと
思います。
ヘキサドライブは楽しく、そして力強いゲーム開発をこれからも
続けていきます。