Linuxでプログラムを動かすとき、ポインタのサイズが8バイトか4バイトかで、メモリの使い方や速度が変わります。今日は、この「x32 ABI」という仕組みをJanet言語で検証した、ある開発者の実装知見を掘り下げます。32ビットポインタのまま64ビットの命令セットを使うことで、メモリを抑えつつ速度も保てるという話ですが、主要ディストリビューションでの扱いにはばらつきがあり、検証には古いUbuntu環境まで持ち出す必要がありました。

開発者Hailey、x32でMastodonのメモリ使用量を650MBから350MBへ

x32 ABIとは、かみ砕いて言えば「住所の書き方を短くすることで、荷物の置き場所を増やす」ような仕組みです。64ビットCPUの命令セットはそのまま使いながら、メモリ上の番地(ポインタ)だけを32ビット、つまり半分のサイズで扱います。番地情報が小さくなる分、同じキャッシュやメモリに収まるデータが増え、プログラムが軽く速く動く余地が生まれます。

この仕組みを実際に検証したのが、開発者Alex Alejandre氏による記事です。Lobstersに掲載されたこの記事には、開発者Haileyによるコメントが引用されており、そこでは「ポインタを多用するヒープを持つプログラムでは、64ビットシステムでも32ビットポインタを使うことで、メモリをほぼ半分近くまで節約でき、キャッシュに収まるデータが増える分、プログラムの速度も多少上がる」と説明されています。Haileyが実際にMastodonをx32 ABI上で動かしたところ、アプリのメモリ使用量は650MBから350MBへ下がったとされています。半分弱の削減にあたり、仕組みが成立すれば効果はそれなりに具体的だと分かります。

ただし、同じコメントでHaileyは「この仕組みはLinuxのx32 ABIで実現できるが、悲しいほど使われておらず見過ごされている」とも述べています。Debianではデフォルトで無効化されており、ブートフラグを立てれば有効化できるものの、Arch Linuxに至ってはそもそもコンパイルに含まれていません。ソフトウェアの大半はx32向けにビルドできるものの、パッケージがほとんど存在しないため、ほぼ自力でビルドし直す必要があるという条件も明記されています。Haileyはその理由を「地道な調整と周知の作業が中心で、自分一人で推し進める時間や意欲がない」と説明しており、技術的な障害というより、普及のための手間が足かせになっているという位置づけです。

この「ILP32をx86-64上で使う」という設計思想自体は新しいものではありません。Wikipediaの記述によれば、Solarisは以前からSPARCとx86-64の両方でこうしたユーザー空間を提供しており、Debianも同様のILP32ユーザー空間を持っています。x32 ABIが優れているとされる計測結果として、SPEC CPU 2000の181.mcfベンチマークでは、x32版がx86-64版より40%速かったという記録があります。また、SPEC CPU整数ベンチマーク全体では平均5〜8%速く、浮動小数点ベンチマークでは速度面の優位はなかったとされています。この数値を基準に考えると、Haileyが報告したMastodonのメモリ削減幅は、ベンチマークで確認されている速度面の効果とは別の軸の成果だと分かります。

x32 ABIの経緯についても出典は明記しています。Athlon 64が2003年に登場して以降、32ビットポインタを持つx86-64 ABIの利点は複数の人物が議論してきたとされ、2008年にはDonald Knuth氏もこの点に言及したと記録されています。実装が公に進み始めたのは2011年8月27日で、Hans Peter Anvin氏がLinuxカーネルメーリングリストでH. J. Lu氏との共同作業を発表しました。同日、Linus Torvalds氏はx32 ABIが32ビットの時刻値を使うことへ懸念を示し、これが2038年問題につながる点を指摘したとされています。この指摘を受けて、開発チームは時刻値を64ビットへ変更しました。x32 ABIはLinuxカーネル3.4でマージされ、GNU C Libraryのバージョン2.16でサポートが追加されています。2018年12月には非推奨化の議論がありましたが、2023年4月時点では実施されておらず、2024年5月には新しい開発の動きも見られたと記されています。

開発者Alejandre、Arch LinuxとUbuntuでの検証結果を提示

Alejandre氏自身の検証は、出典記事がどこまで説明しているかという範囲に沿って追うと輪郭がはっきりします。氏はまずArch系のCachyOSで、lib32-glibcとlib32-gcc-libsを使ってビルドを試みました。Archはx32 ABI自体をコンパイルに含めていないため、代わりに-m32フラグを使うしかありません。その結果について、Alejandre氏は「20%のメモリ削減、しかし50%遅くなった」とまとめています。-m32は従来の32ビットx86モードで、レジスタを8個しか使わないため、Haileyが説明した「64ビット命令セットのまま32ビットポインタを使う」という本来のx32 ABIの効果とは異なるというのが、Alejandre氏の見立てです。速度面の効果を得るには-mx32フラグが必要ですが、Arch環境ではLinuxカーネル自体を再コンパイルしない限りそれができないと記事は述べています。Ubuntuについても、サポートが落とされている点が併記されています。

そこでAlejandre氏が検証環境として選んだのが、サポート期限を終えたUbuntu 20.04 LTS(Focal Fossa)でした。標準サポートは2025年5月31日に終了しているとされ、gccのバージョンは9.4.0とやや古いものの、build-essential、git、gcc-multilib、libc6-dev-x32といった必要なパッケージは揃っていたと記事は説明しています。この環境で32ビット版と64ビット版のビルドスクリプトを用意し、words.janet(テキストを単語に分割して数え、ソートする処理)、records.janet(構造体を部門ごとにグループ化して集計する処理、実際のコードに近い未使用フィールドを含む)、parse.janet(PEGで行を解析して合計する処理)という複数のベンチマークを走らせたとされています。一方で、型付きC配列を使って速度を稼ぐdeclarative-dslsについては、こうしたポインタサイズ縮小の恩恵をあまり受けない「最悪のケース」だとAlejandre氏自身が位置づけています。具体的な速度・メモリの数値そのものは、今回確認した出典の抜粋には記載がありません。

この検証を踏まえ、Alejandre氏は「Linuxディストリビューションは-mx32サポートを含めるべきで、デーモンやユーティリティは日常的なコンピューティングのためにこの形式でコンパイルされるべきだ」と主張しています。フラグ一つのコストで得られる効果だという立場です。さらに、Janet言語自体の実装についても言及があり、Janetのヒープオブジェクトはガベージコレクタのために16バイトを使っているとされ、構造体やテーブルでは配置を見直すことで8バイトを取り戻せる可能性がある、一方でglibcのmallocが8バイトを追加し16バイト単位に切り上げるため、構造体自体のサイズは変わらないだろうという技術的な見通しも記されています。この部分はAlejandre氏の考察であり、実装済みの成果ではない点には注意が必要です。

用語補足:x32 ABI

x32 ABIは、64ビットCPUの命令セットと高速化機能(レジスタ数の多さ、浮動小数点性能、位置独立コードの高速化など)を使いながら、プログラム内のポインタだけを32ビットに抑える仕組みです。アドレス空間は4GiBに制限されますが、ポインタが小さい分メモリ使用量が減り、キャッシュに収まるデータが増えることで速度にも効果が出る場合があります。ただし、この記事で示されている「40%高速化」はSPEC CPU 2000の特定ベンチマーク(181.mcf)での数値であり、全プログラムに同じ効果があるわけではありません。整数演算全般では5〜8%程度、浮動小数点演算では優位なしとされており、Mastodonでのメモリ削減(650MBから350MB)は、このベンチマーク計測とは別の実環境での報告である点も区別して読む必要があります。

注目ニュース

Lobstersの投稿者たち、プログラミングの「勘」を共有

lobste.rsのスレッドでは、検証していない技術的な「勘」を募る投稿に、複数の反応が寄せられています。ある投稿者は、クロスプラットフォームGUIツールキットをレンダリングではなくアクセシビリティから設計し始める方が、より早く完成度の高いツールキットに到達できるという見立てを述べています。別の投稿者は、アクセシビリティツリーが開発初期から存在することで、テストの書きやすさやダークモード対応など、開発者がアプリの挙動を検証しやすくなる可能性を挙げています。duckdbがparquetファイルから必要なバイト列だけを取り出せるかを深掘りしたいという声もあり、いずれも検証済みの結論ではなく、今後確かめたい仮説として語られています。

Anthropic、Claude Haiku 5.5をGPT-6 Lunaと同価格で発表

Anthropicは新しい低コストモデル「Claude Haiku 5.5」を発表しました。Simon Willison氏のブログによると、前身のHaiku 4.5は入力100万トークンあたり1ドル、出力5ドルという価格で、先行月に登場したOpenAIのGPT-6 Lunaの10倍の価格だったとされています。新しいHaiku 5.5は、10万トークンまでは入力0.10ドル・出力0.50ドルとLunaと同額に設定され、10万トークンを超えると価格は5倍の入力0.50ドル・出力2.50ドルへ上がります。Luna自身も27万2000トークンを超えると価格が上がりますが、上昇幅は入力0.20ドル・出力0.75ドルにとどまるとされています。Willison氏はまた、Haiku 5.5が新しいトークナイザーを採用した結果、同じ長文プロンプトでもHaiku 4.5よりおよそ1.25倍のトークン数を消費すると指摘しており、これは表には出ない価格上昇にあたると述べています。10万トークン以内の用途ではLunaと同価格でベンチマークスコアも高いとされる一方、それを超える用途ではLunaの方が有利だという比較がなされています。

編集後記:フラグ一つのコストという表現の射程

Alejandre氏が記事で使った「フラグ一つのコスト」という言葉が印象に残ります。-mx32という一行の指定だけで効果が得られるという主張ですが、同じ記事は、Arch Linuxがそもそもx32 ABIをコンパイルに含めていないこと、Ubuntuもサポートを落としていることを並べて書いています。つまりフラグ一つで済むのは、OS側がその選択肢を用意している場合に限られるという条件が、文章の中にすでに織り込まれています。検証のためにサポート終了済みのUbuntu 20.04まで持ち出した経緯からも、今この仕組みを試すこと自体に相応の環境準備が要ることがうかがえます。普及が進んでいない理由をHaileyは「技術より調整と周知の手間」だと述べていましたが、Alejandre氏の検証過程は、その手間の中身を具体的に示す記録になっています。