[ Home | Programming Tips | Mail ]
領域管理に bit map arrayを使っていたりすると long中で上位 bitから
探して最初に ON or OFFなっている bitを求めたいことがよくあります。
もろに性能にひびく部分ですから高速であることが要求されます。
Cで書くとこんな感じでしょうか。
Cではこれ以上速い Codeは書けませんが PowerPCには便利な命令があります。
Metrowerks C++では C/C++中に混在はできませんが Assemblerで関数を書けますので
1命令だけの関数を作ってしまいましょう。
unsigned long word;
long bitnum;
for ( bitnum = 0; bitnum < 32; bitnum++ ) {
if (word & (0x80000000UL >> bitnum)) break;
}
if (bitnum < 32) {
// on bitあった
}else{
// on bitない
}
これを使うと
// wordの先頭から続いている 0の bit数を返す。
asm long AsmCountLeadingZeroBits(register unsigned long word)
{
cntlzw r3,word // 1 Clock
blr
}
でおしまいです。Cでは数十 Clockかかりますが Assemblerでは Branch Foldされることを
考慮すればほとんど 1 Clockです。onじゃなく offの bitを探したい場合は notを取って AsmCountLeadingZeroBits()に与えてください。 unsigned long word;
long bitnum;
bitnum = AsmCountLeadingZeroBits(word);
if (bitnum < 32) {
// on bitあった
}else{
// on bitない
}
PowerPC+最適化 Compilerの組み合わせでも Assemblerは知っていた方が
良いようですね。
と言っている内に CodeWarrior 11で __cntlzw()という Intrinsic functionが追加されて単に
と書ける様になりました。あら簡単。
bitnum = __cntlzw(word);
この Pageは MacOS X + Radio UserLand で作っています。