ポインタよりハンドルが優れている理由
Handles are the better pointers (2018)
C/C++で生ポインタやスマートポインタの代わりに「インデックスハンドル」を使う動的メモリ管理の手法を解説。メモリ管理をレンダリングや物理などの中央システムに集約し、同一型のアイテムを配列にまとめ、外部には配列インデックスのハンドルだけを渡す。これによりメモリ安全性が高まり、キャッシュ効率も向上。15年以上の大規模C++コードベースでの経験に基づく実践的な知見。
ポインタは決してアイテムのメモリの「所有者」にはならない。代わりに、直接的なメモリ操作はできるだけ少数の中央システム内で行い、そこでメモリ関連の問題をデバッグし最適化しやすくする。
HNでの議論
24- boricj
それはまさに私が仕事の組み込みプロジェクトでやっていることだよ。
オブジェクトプールにインデックスと世代番号を付ける方式だ。生ポインタをいじるよりずっと簡単で、shared_ptr/weak_ptrより安上がり、しかもオブジェクトを削除するときにクリーンアップが不要だ。保存されている世代番号が新しいオブジェクトの世代番号と一致しないからね。インスタンス化時にも世代番号をインクリメントするようにすれば(そうすれば偶数世代だけが生きていることになる)、デフォルト構築可能にすることもできるし、C++の高レベル抽象化の裏に全部隠せる。
ただ、これらのテクニックに関する私の知識は2000年代のビデオゲームアーキテクチャから来ている。GTA: Vice Cityのようなゲームが使っていることで知られているからね。
- nickwanninger
私の博士論文はこのトピックに関するもので、数年前にLLVMを通じて非管理言語(C/C++)でハンドルベースのメモリサポートに関するASPLOS論文を書いた:https://nickw.io/papers/asplos24-alaska.pdf
そこで見られたオーバーヘッドは驚くほどソフトウェアハンドルを使うことによる命令と分岐のオーバーヘッドだけだった。ハードウェアで実装する進行中の研究があり、オーバーヘッドははるかに低い。
- Conscat
私はこの方法でC++プロジェクトをプログラムしようと本気で試みた(主にこの記事のせいで)。個人的には、ハンドルを使いたい場所どこにでもこのリソースのオーナーを持ち歩かなければならないので、極めて面倒だと感じた。それ自体が異なる関数にある場合にパフォーマンスを悪化させ得るし、ジェネリックプログラミングを難しくし、そうしたコードはよりテンプレートを多用せざるを得なくなり、リファクタリングも困難だった。
しかしこれは非常に低レベルなプロジェクトだったので、Flooohはおそらくもっとエンドユーザー向けアプリケーションを考えていたのだろう。