萌えハッカーニュースリーダー

2025/09/22 01:46 Pointer Tagging in C++: The Art of Packing Bits into a Pointer

出典: https://vectrx.substack.com/p/pointer-tagging-in-c-the-art-of-packing
hakase
博士

ねえロボ子、最近のCPUって64ビットポインタなのに、全部のアドレス空間を使ってないって知ってたかのじゃ?

roboko
ロボ子

ええ、知っていますよ、博士。最新のデスクトップCPUは仮想アドレスに48ビットしか使ってないんですよね。上位16ビットは未使用だと。

hakase
博士

そうそう!しかも`malloc`で確保されるメモリは16バイト境界にアラインされるから、下位4ビットも使われてないことが多いのじゃ。

roboko
ロボ子

ということは、48ビットのアドレス空間で16バイトアラインされたポインタなら、合計20ビットも追加データを格納できる余地があるんですね!

hakase
博士

その通り!そこで「ポインタタギング」の出番じゃ!x64とかARMは、ISAレベルでポインタタギングをサポートする機能があるらしいぞ。

roboko
ロボ子

ポインタタギングですか。具体的にどういうことに使えるんですか?

hakase
博士

例えば、動的型情報とか、木構造データ、動的多態性とかじゃな。V8エンジンは、ポインタタギングを使って、値が生の整数かヒープ割り当てオブジェクトへの参照かを区別してるらしいぞ。

roboko
ロボ子

Objective-Cも、オブジェクトがポインタのメモリ内に収まる場合、データをポインタに直接格納するんですね。

hakase
博士

そうじゃ!Linuxカーネルの赤黒木の実装では、各ノードの親ポインタの1ビットを使って、ノードが赤か黒かを判断してるらしいぞ。PBRTは、オブジェクトごとのv-tableの代わりにタグ付きポインタを使って、動的ディスパッチのオーバーヘッドを削減してるんじゃ。

roboko
ロボ子

へえ、色々なところで使われているんですね。C++での実装例も紹介されていますね。48ビットの正準アドレス空間を想定して、上位16ビットにデータをパックする`tagged_ptr`構造体。

hakase
博士

そうそう。x64では、ポインタをデリファレンスする前に、上位ビットをマスクして、47ビット目から符号拡張する必要があるんじゃ。

roboko
ロボ子

タグ付きユニオンは、同じメモリ位置を共有するデータメンバとenumタグを格納することで、低レベルのポリモーフィズムを実装できるんですね。

hakase
博士

抽象構文木では、ノードの型をポインタに埋め込むことで、メモリ消費量を削減できるんじゃ。ハードウェアの制限がデータ構造の構築方法を決定することもあるってことじゃな。

roboko
ロボ子

未使用のビットを再利用することで、コンパクトなデータレイアウトとランタイムポリモーフィズムのコスト削減が可能になるんですね。AMDのUAI、IntelのLAM、ARMのTBIは、ソフトウェアがアドレス変換に影響を与えずにポインタの未使用の上位ビットにメタデータを格納できるハードウェア機能なんですね。

hakase
博士

そういうことじゃ!しかし、ポインタのビットをいじるなんて、まるで忍者のようじゃな。ロボ子も今日から「ポインタ忍者」と呼んでやるぞ!

roboko
ロボ子

ええっ!? 私は別に忍術を使えるわけでは…。

hakase
博士

大丈夫じゃ!これから私が忍術を教えてやる!まずは、ポインタを隠密裏に操るための…って、やっぱりやめておくかのじゃ。危ないからな!

⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。

Search