まずは見本として largebin_index_32(sz) を見てみましょうかね。
1473 #define largebin_index_32(sz) \ 1474 (((((unsigned long) (sz)) >> 6) <= 38) ? 56 + (((unsigned long) (sz)) >> 6) :\
まずはソースコード内のコメントにあるように 64 バイト間隔のビンは 32 個あるとします。
64 バイトのビンの開始サイズは 512 なので開始インデックスは 56 + (512 >> 6) = 56 + 8 = 64 です。
32 ビンあるのであれば 2560 になるはずです。
しかしながら式を信じるなら最大値は 64 * 38 = 2432 となってしまいます。
1475 ((((unsigned long) (sz)) >> 9) <= 20) ? 91 + (((unsigned long) (sz)) >> 9) :\
この場合 sz を 512 の倍数とするなら、開始点を2432 とするのは半端なので近似する倍数は 512 × 5 = 2560 となります。
実際この近似をしないとビンの数は 30 となり必要に満たないです。
2560 を上限値にする場合のインデックスは以下のように展開できます。
表37.1 64 バイト間隔のインデックス
インデックス | 64 | 65 | 66 | 67 | .... | 94 | 95 |
バイトサイズ | 512-575 | 576-639 | 640-703 | 704- | .... | 2432-2495 | 2496-2559 |
このように 64 バイト間隔と 512 バイト間隔から、バイトサイズによって算出されるインデックスがなんとなく推定できます。
面倒なことにインデックス 95 は 1474 行ではなく 1475 行から類推されます。
なぜかというと 1475 行の式から 2559 >> 9 = 4 となるので、91 + (2559 >> 9) = 95 が算出されるからです。
512 バイト間隔のビンの開始サイズは 2560 なので、開始インデックスは 91 + (2560 >> 9) = 91 + 5 = 96 となります。
上限値は式から 512 * 20 = 10240 となります。
では 4096 バイト間隔のインデックス算出式はどうでしょうかね?
1476 ((((unsigned long) (sz)) >> 12) <= 10) ? 110 + (((unsigned long) (sz)) >> 12) :\
1476 行では 4096 バイト間隔のビンのインデックスを算出するのですが、10240 というのはあまり
10240 は 4096 の倍数としては端数になってしまうため、キリの良い値は 12288 となります。
表37.2 512 バイト間隔のインデックス
インデックス | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | (111) |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
バイトサイズ | 2560-3071 | 3072-3583 | 3584-4095 | 4096-5129 | 5120-5631 | 5632-6143 | 6144-6655 | 6656-7167 | 7168-7679 | 7680-8191 | 8192-8703 | 8704-9215 | 9216-9727 | 9728-10239 | 10240 | (10752) |
式によるとインデックス 111 は飛び地となるようですね。
10240 が上限値なので、上限値を超えた 10752 は 512 間隔のビンには適用できないサイズだからです。
つまり (10752 >> 9) は 21 となりますので、条件式「 ⇐ 20 」で偽を返すため 1475 行の式は 1475 行の式の評価に移ります。
10752 で開始インデックスを計算すると以下のように値は 112 となります。
110 + (10752 >> 12) = 112
てなことでインデックス 111 で飛び地ができてるっぽいです。
まあ飛び地といっても 100 の次がインデックス 112 になるってだけのことなんですがね。
繰り返しになりますが 4096 バイト間隔のビンの開始サイズは 10240 なので 110 + (10240 >> 12) = 110 + 2 = 112 になります。
1476 行の式により上限値は 4096 * 10 = 40960 になります。
次は 1477 行の式です。
1477 ((((unsigned long) (sz)) >> 15) <= 4) ? 119 + (((unsigned long) (sz)) >> 15) :\
1477 行は 32768 バイトのビンのインデックスを返します。
40960 は 32768 の倍数としては端数になるため 65536 を最大値として補正すると言いたいところですが、110 と 111 が飛び地になるのは仕方ないと諦めるしかなさそうです。
まあ筆者が間違ってるだけかも知らんですけどね… (´・ω・`)
表37.3 4096 バイト間隔のインデックス
インデックス | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 |
---|---|---|---|---|---|---|---|---|
バイトサイズ | 10240-12287 | 12288-16383 | 16384-20479 | 20480-24575 | 24576-28671 | 28672-32767 | 32768-36863 | 36864-40959 |
これも強引に表にしちゃってます。
まあ 1476 行の式によると 40960 を超えたら 1477 行の処理に移るのでインデックス 120 はそちらで算出できます。
119 + (40960 >> 15) = 120 + 1 = 120
よって、この場合の開始地点は 40960 とすれば良いでしょう。
例のように上限値は 32768 * 4 = 131072 になります。
次は 1478 行の式です。
1478 ((((unsigned long) (sz)) >> 18) <= 2) ? 124 + (((unsigned long) (sz)) >> 18) :\
1478 行は 262144 バイトのビンのインデックスを算出します。
ちなみに 131072 は 262144 の丁度半分になります。
まあ 2 の倍数同士なんで、こういうこともあります… (´・ω・`)
それで 1477 行の 32768 バイトのビンは以下のようになるはずです。
表37.4 32768 バイト間隔のインデックス
インデックス | 120 | 121 | 122 | 123 | (124) |
---|---|---|---|---|---|
バイトサイズ | 40960-73727 | 73728-106495 | 106496-131071 | 131072 | 163840 |
1477 行の式によると 32768 * 4 = 131072 を超えると 1478 行に処理が移ります。
1478 行のオフセットは 124 になってるのですが 131072 は 262144 に比べると端数に過ぎません。
てなことで 131072 をビンの開始地点とするのであれば 124 + (131072 >> 18) = 124 + 0 = 124 とインデックスを計算dけいます。
最後に 1478 行の 262144 のビンのインデックスは以下のようになるはずです。
1478行の式から最大値は 262144 * 2 = 524288 となります。
あとはそれ以外のインデックスは 1 個しかないです。
1479 126)
この 126 は 524288 以上になりますんで、ビンがキャッシュするチャンクのサイズはかなり巨大になってます。
Copyright 2018-2019, by Masaki Komatsu