l'essentiel est invisible pour les yeux

Saturday, December 02, 2006

[Cell] SPUで分岐ヒント命令を明示的に書くが

うまく動作しない。

SPUは26段の深いパイプラインを持つため、分岐予測が外れた場合には15サイクルのペナルティが発生する。この分岐ペナルティへの対処として、SPUではハードウェア的な分岐予測回路ではなく、ソフトウェア的に分岐予測へのヒントを与える分岐ヒント命令を実装している。

分岐ヒント命令を与えた場合と与えない場合でどれほど実行速度に差が出るか計測してみた。SPE上で実行時間計測には、[Cell] SPE上での実行時間計測を利用した。


#include <stdio.h>
#include <spu_intrinsics.h>
#include "../spe_time.h"

#define likely(cond) __builtin_expect((int)(cond), 1)
#define unlikely(cond) __builtin_expect((int)(cond), 0)

static const int N = 100000;
void nope(void){}

int main() {
int i;
unsigned int t1, t2;

// 条件分岐を含むループƒ—
StartTimer(t1);
for(i=0;i<N;i++) {
if(i>100000) nope();
}
StopTimer(t1);

// 分岐ヒント命令を与えた条件分岐を含むループƒ—
StartTimer(t2);
for(i=0;i<N;i++) {
if(unlikely(i>100000)) nope();
}
StopTimer(t2);

PrintTimer(t1);
PrintTimer(t2);

return 0;
}


実行
#./spu.out
timer: 0.43780(msec)
timer: 0.468720(msec)
#

最適化なし。-O3で最適化すると実行速度はどちらも同じになる。
分岐ヒント命令を与えたほうが遅くなってるし。。
分岐ヒント命令を与えたループと与えないループのアセンブリコード。

42,44c42,45
< lqd $2,64($sp)
< ila $3,100000
< cgt $2,$2,$3
---
> lqd $3,64($sp)
> ila $2,100000
> cgt $2,$3,$2
> sfi $2,$2,0


unlikeyマクロで定義した(int)(cond)と0の比較を行うための、SFI $2, $2, 0という減算処理命令が追加されている。(下側が分岐ヒント命令を与えたアセンブリ)
その分実行速度が遅くなった様子。

分岐ヒント命令は、hbr, hbra, hbrrというニーモニックで与えられるのだが生成されたアセンブリコードには該当する命令はなかった。シュミレーター上では分岐ヒント命令は動作しない??

参考
Cell Broadband Engine Programming Tutorial Version 1.1