2

http://www.alex-ionescu.com/?p=50 .

上記の投稿を読みました。著者は、Windows x64 が単一リンク リストの例で 44 ビットの仮想メモリ アドレスのみをサポートする理由を説明しています。

struct {  // 8-byte header
        ULONGLONG Depth:16;
        ULONGLONG Sequence:9;
        ULONGLONG NextEntry:39;
} Header8;

最初の犠牲は、シーケンス番号のスペースを 16 ビットではなく 9 ビットに減らし、リストが達成できる最大シーケンス番号を減らすことでした。これでもポインター用に 39 ビットしか残っていません。これは 32 ビットよりも平凡な改善です。割り当て時に構造体を強制的に 16 バイト アラインすることで、最下位ビットを常に 0 と見なすことができるようになったため、さらに 4 ビットを獲得できました。


ああ、私は理解できません。

「割り当て時に構造体を強制的に 16 バイト アラインすることで、最下位ビットを常に 0 と見なすことができるようになったため、さらに 4 ビットを獲得できました。」意味?

4

2 に答える 2

3
16 is 0010000 in binary

32 is 0100000 in binary

64 is 1000000 in binary

16 の倍数であるすべての数値について、最後の 4 ビットは常にゼロであることがわかります。したがって、これらのビットを格納する代わりに、それらを除外して、ポインターを使用するときに再び追加することができます。

于 2010-12-30T14:23:56.500 に答える
2

2^N バイトにアラインされたポインターの場合、そのアドレスは常に 2^N で割り切れます。これは、下位 N ビットが常にゼロであることを意味します。それらに追加情報を保存できます。

encode ptr payload = ptr | payload
decode_ptr data = data & ~mask
decode_payload data = data & mask

ここで mask は(1 << N) - 1- つまり、下位 N ビットが設定された数値です。

このトリックは、低レベル コードのスペースを節約するためによく使用されます (ペイロードは、GC フラグ、型タグなどにすることができます)。

実際には、ポインターを格納しているのではなく、ポインターを抽出できる数値を格納しています。もちろん、デコードせずに数値をポインターとして逆参照しないように注意する必要があります。

于 2010-12-30T14:23:17.070 に答える