a, int n, int x) { int lo = 0, hi = n; while (lo < hi) { int m = (lo + hi) / 2; if (x < a[m]) hi = m; else if (x > a[m]) lo = m + 1; else return m; } return hi; }
分岐予測は期待できない int bsearch(int* a, int n, int x) { int lo = 0, hi = n; while (lo < hi) { int m = (lo + hi) / 2; if (x < a[m]) hi = m; else if (x > a[m]) lo = m + 1; else return m; } return hi; }
2. ランダムなメモリアクセス 分岐予測は期待できない 参照の局所性どうなの? int bsearch(int* a, int n, int x) { int lo = 0, hi = n; while (lo < hi) { int m = (lo + hi) / 2; if (x < a[m]) hi = m; else if (x > a[m]) lo = m + 1; else return m; } return hi; }
2. ランダムなメモリアクセス 分岐予測は期待できない 参照の局所性どうなの? int bsearch(int* a, int n, int x) { int lo = 0, hi = n; while (lo < hi) { int m = (lo + hi) / 2; if (x < a[m]) hi = m; else if (x > a[m]) lo = m + 1; else return m; } return hi; } _人人人人人人人人人人人人_ > プロセッサと和解せよ <  ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^Y ̄
n, int x) { int lo = 0, hi = n; while (lo < hi) { int m = (lo + hi) / 2; if (x < a[m]) hi = m; else if (x > a[m]) lo = m + 1; else return m; } return hi; } 予測が要らない or しやすい実装にしよう! どうするか?
❏ 分岐予測を要求しない! Loopも厳密に⎡log 2 n⎤回 int bsearch_bf(int* a, int n, int x) { int* b = a; while (n > 1) { int m = n / 2; b = (b[m] < x) ? &b[m] : b; n -= m; } return (*b < x) + b - a; } 探索エリアの先頭ポインタを更新し、エリアを絞ってるだけ でもこれで制御ハザードが緩和できる!