37.2. 64 ビットアーキテクチャのビン

注記

largebin_index_32(sz) と largebin_index_64(sz) マクロは 64 バイト間隔のビンの処理を除くと同じコードになっています。したがってこの項目は 32 ビットの説明をスキップした方が読めば良いでしょう。

筆者の検証環境では 16 バイトアラインメント、64 ビットアーキテクチャなので largebin_index_64(sz) が該当します。

1492 #define largebin_index_64(sz)                                                \
1493   (((((unsigned long) (sz)) >> 6) <= 48) ?  48 + (((unsigned long) (sz)) >> 6) :\

まずは 1493 行ですね…

smallbin_index(sz) によると 64 ビットアーキテクチャ、 16 バイトアラインメントは 1023 が上限なので、 Large bin は 1024 バイトが開始点になります。

つまり式を組み合わせると開始インデックスは 48 + (1024 >> 6) = 48 + 16 = 64 になります。

64 バイト間隔のビンの上限値は 64 * 48 = 3072 となります。

まあ以下のようになるでしょうね。

インデックス64 65 66 95 (96)
ビンサイズ  
1024-1087
1088-1151
1152-1215
...
3008-3071
 (3072)

64 バイト間隔のビンは 32 あるという想定だとインデックス 96 は 512 バイト間隔のビンと重なりそうな箇所ですが、1494 行でどのように扱われてるかチェックしましょう。

1494    ((((unsigned long) (sz)) >> 9) <= 20) ?  91 + (((unsigned long) (sz)) >> 9) :\

512 バイトのビンの開始インデックスは 91 + (3073 >> 9) = 91 + 6 = 97 となります。

この解釈正しいんですかね…

(´・ω・`)

何故迷うかというと 3072 のインデックスは 96 、次は 3073 のインデックスが 97 になるだけなので、64 バイトでなく 512 バイトのサイズに入れても問題ないですから…(喉からから)

インデックス(96) 97 98 99 110 111 (112)
ビンサイズ  
(3072) 
3073-3583
3584-4095
4096-4607
...
9728-10239
 10240 
 (10752)

512 バイト間隔のビンの開始点は 3073 なので 91 + (3072 >> 9) = 91 + 6 = 97 です。

つまり 96 は実質的には飛び地になるようです。

ちなみに上限値は 512 * 20 = 10240 となりますが、これだと 512 バイト間隔のビンの最後のインデックスは 111 となるべきのような気がします。

仕様だと 16 ビンあるはずでし、やはり 96 , …. , 111 が正しい範囲っぽそうです。

問題はインデックス 112 がどうなるかなので、次の条件式を見てみましょう。

1495    ((((unsigned long) (sz)) >> 12) <= 10) ? 110 + (((unsigned long) (sz)) >> 12) :\

これによると 10241-10752 は 4096 の倍数にならない値は端数となります。

110 + (10752 >> 12) = 110 + 2 = 112

次のインデックスは 4096 * 2 = 12282 になるまで動きがありません。

110 + (12288 >> 12) = 110 + 3 = 113

4096 バイト間隔のビンの開始は 10241 からなので 110 + (10241 >> 12) = 110 + 2 = 112 がインデックスになります。

さらに上限値は 4096 * 10 = 40960 となります。

そうすると 4096 バイト間隔のインデックス範囲は 112 , …, 119 または 113 , …, 120 になるはずです。

まあでも仕様に忠実とするなら 112, 113, …, 119 のほうが良さそうです。

たぶん以下のような感じになりますね。

インデックス 112 113 114 115 116 117 118 119 (120)
ビンの範囲  
10241-12287
 12288-16383
 16384-20479
 20480-24575
 24576-28671
 28672-32767
 32768-36863
 36864-40959
 (40960)

念の為にインデックス 120 がどうなるのか次のビン( 32768 バイト間隔)の条件式でチェックしてみましょう。

1496    ((((unsigned long) (sz)) >> 15) <= 4) ? 119 + (((unsigned long) (sz)) >> 15) :\

32768 バイト間隔のビンの開始インデックスは 119 + (40960 >> 15) = 119 + 1 = 120 と計算できます。

さらに上限値は 23768 * 4 = 131072 になります。

この情報から推測すると以下のようになるはずです。

インデックス
120         
121           
122            
123
ビンのサイズ
40960-73727 
 73728-106495 
 106496-131071 
 131072

てことで 120, …, 123 が 32768 バイト間隔のインデックス範囲となるはずです。

もちろん計算が間違いでなければですが… (´・ω・`)

では 262144 バイト間隔のビンの条件式も見てみましょう。

1497    ((((unsigned long) (sz)) >> 18) <= 2) ? 124 + (((unsigned long) (sz)) >> 18) :\
1498    126)

262144 バイト間隔のビンの開始インデックスは 124 + ( 131072 >> 18 ) = 124 + 0 = 124 となりますね。

類推されるビンのインデックスは以下のような配置になるかと思います。

インデックス
124           
125            
 (126)
ビンのサイズ
131072-262143 
 262144-524287 
 524288-

インデックス 126 は大きいのは何でもありって感じのビンですね。

Copyright 2018-2019, by Masaki Komatsu