正直日記



2006/08/16

_ __builtin_expect
粉骨砕身の覚悟でがんばります - __builtin_expect について

中身がループ脱出だけじゃあまり効果が出ないのではないかしら。あとは、
THUMBだから効果が薄いとか……ARMだと、条件フィールドをガシガシ使って
くれるようになる(といいなあ。ジャンプ以外に使っている所をあまり見た
ことが無いのだけど)。

試しに自分の使っているミキサーの、最も内側の部分に適用してみました。
ミキシング中に音声サンプルの再生箇所が終端まで来たら、指定のループポ
イントまで戻すという処理を行っています。

  samp = (snd_dat[pos] * vol);
  do {
    *mxr++ += samp;
    cnt += step;
    if (cnt > TICK_COUNT) {
      pos += cnt / TICK_COUNT;
      cnt &= (TICK_COUNT - 1);
#if BUILTIN_EXPECT
      if (__builtin_expect(pos > size, 0)) {
#else
      if (pos > size) {
#endif
        do {
          pos -= size;
          pos += loop;
        } while (pos > size);
      }
      samp = (snd_dat[pos] * vol);
    }
  } while (--length);
  return;
こんなソースがあって、gcc -marm -Sで吐かせると……
non-expectexpect
 1: .L2:
 2:   ldrb  r3, [r0], #1
 3:   add  r6, r6, r4
 4:   add  r3, r3, r2
 5:   cmp  r6, #65536
 6:   strb  r3, [r0, #-1]
 7:   bls  .L4
 8:   add  sl, sl, r6, lsr #16
 9:   mov  r2, r6, asl #16
10:   cmp  sl, ip
11:   mov  r6, r2, lsr #16
12:   bls  .L6
13: .L16:
14:   rsb  r3, ip, sl
15:   add  sl, r3, lr
16:   cmp  sl, ip
17:   bhi  .L16
18: .L6:
19:   ldrsb  r3, [sl, r9]
20:   mul  r2, r8, r3
21:   and  r2, r2, #255
22: .L4:
23:   subs  r1, r1, #1
24:   bne  .L2
25:   add  sp, sp, #4
26:   ldmfd  sp!, {r4-r9, sl, pc}
 1: .L2:
 2:   ldrb  r3, [r0], #1
 3:   add  r6, r6, r4
 4:   add  r3, r3, r2
 5:   cmp  r6, #65536
 6:   strb  r3, [r0, #-1]
 7:   bls  .L4
 8:   add  sl, sl, r6, lsr #16
 9:   mov  r2, r6, asl #16
10:   cmp  sl, ip
11:   mov  r6, r2, lsr #16
12:   bhi  .L10
13: .L6:
14:   ldrsb  r3, [sl, r9]
15:   mul  r2, r8, r3
16:   and  r2, r2, #255
17: .L4:
18:   subs  r1, r1, #1
19:   bne  .L2
20:   add  sp, sp, #4
21:   ldmfd  sp!, {r4-r9, sl, pc}
22: .L10:
23:   rsb  r3, ip, sl
24:   add  sl, r3, lr
25:   cmp  sl, ip
26:   bls  .L6
27:   rsb  r3, ip, sl
28:   add  sl, r3, lr
29:   cmp  sl, ip
30:   bhi  .L10
31:   b  .L6
確率の低い方を下の方に持ってきてくれています。あと確率に従って何気に ループ展開してる気がする。8和音合成@20KHzだと non-expect版のCPU負荷 が20.9%なのに対してexpect版が19.6%と、ちょっと大分かなり少し速くなる みたい。 で、例によって条件フィールドはあまり使ってくれてないわけですが、一つ 思ったのは、thumbだと条件分岐は相対で256バイト内までしか飛べないので、 ややこしい処理が長くなるとどうしても無条件分岐が必要になり、旨みが無 くなるんじゃないかしら。 それにしても、これは多分、物凄く素直に効いた例だろうなあ。自分のヘボ さを再確認したかもしれん。

tekezo >
コメントありがとうございます。

当初の目論見では「__builtin_expect を使っても使わなくても
あんまりかわらないけど、まあ適切に使っておいたほうが
ちょっぴり速いですね」くらいだろうなぁと思っていたのですが、
実際には広域的な最適化が解除されて
ガクッと速度が低下する結果になったのがセツナイところです。
確かに局所的には最適なコードを吐いてくれているんですけれども
なんで、局所的な最適化で止めておいてくれないのかと。

使い方に気をつければ便利な機能だとは思うのですが、
一度非道い目にあうと、使うことを躊躇してしまいますねぇ……。
 (2006/08/17 01:06:12)
> むしろ残りの条件分岐全てを likely 指定することで難読化してしまうソリューション(目的を見失ってます)。  (2006/08/17 03:17:55)

最新
2009 | 01 02 03 04 05 06
2008 | 01 02 03 04 05 06 07 08 09 10 11 12
2007 | 02 03 04 05 06 07 08 10 11 12
2006 | 01 02 03 04 05 06 07 08 09 10 11 12
2005 | 01 02 03 04 05 06 07 08 09 10 11 12