概要
- 巨大バイナリ問題 は、特大規模のコードベースでのみ顕在化する現象
- 2GiB「リロケーションバリア」 がx86_64アーキテクチャの制約
- 静的リンク によりバイナリサイズが急増し、ジャンプ命令の制限に直面
- -mcmodel=large で制限回避可能だが、命令肥大化などの副作用あり
- さらなる解決策 は今後の議論対象
特大規模コードベースにおける巨大バイナリ問題
- PhD研究や論文投稿 時に、超大規模な問題への理解不足を指摘される課題
- Google等のメガコードベース でのみ発生する現象の観測
- 25GiB超のELFバイナリ (デバッグシンボル含む)の実例
- 静的リンク による全コードの取り込みでバイナリ肥大化
- デプロイや起動高速化 のための静的ビルド選択
2GiB「リロケーションバリア」の正体
- x86_64のCALL命令 は32bit符号付き相対オフセットのみ許容
- 2^31(約2GiB) がジャンプ可能な最大範囲
- 巨大バイナリ では関数間距離が2GiBを超えるケースが発生
- 相対ジャンプの限界 が「リロケーションバリア」と呼ばれる理由
実例:シンプルな相対ジャンプとリロケーション
- C言語の関数呼び出し をgccでコンパイルし、objdumpで解析
- e8(CALL命令) が4バイトの相対位置を指定
- readelfによるリロケーション情報 の確認
- リンカスクリプト で関数を2GiB以上離すことで「relocation overflow」発生
- エラーメッセージ 例: relocation R_X86_64_PLT32 out of range
回避策:-mcmodel=largeの利用
- -mcmodel=large で64bit絶対アドレスジャンプに切り替え可能
- 命令列が5バイト→12バイト に増加(MOVABS+CALL)
- 汎用レジスタ(例: %rdx) の消費増加
- 命令肥大化 によるバイナリサイズ増加・パフォーマンス影響
- -fno-asynchronous-unwind-tables で追加データによるオーバーフロー防止
mcmodel=largeのデメリット
- 命令バイト数増加 によるバイナリ肥大化
- レジスタ消費 によるレジスタプレッシャー増
- 理論上IPC低下 の可能性(実ベンチマークでは再現困難)
今後の展望と課題
- 小規模コードモデル を維持しつつ制約を回避する新戦略の必要性
- さらなる解決策や工夫 は今後の執筆で検討予定
25 GiBのバイナリって、ちょっと怖すぎるよね。動的リンクが必要なんじゃないかな。