首先翻譯維基百科對 x32 ABI 的定義:php
x32 ABI (應用程序二進制接口) 是一個開發中的 Linux 項目,爲 x32 ABI 編譯的程序將能運行在 x86-64 指令集環境的 64 位模式下,但僅僅使用 32 位大小的指針和數據類型。這儘管限制了這個程序最多隻能使用 4GB 的虛擬地址空間,但卻減小了這個程序佔用的內存,而且在某些狀況下能使程序運行的更快。最好的測評結果來自 SPEC CPU2000 中的 181.mcf,結果顯示 x32 ABI 的版本比 x86-64 的要快 32%。CPU2000 測評的整數計算部分,x32 比 x86-64 平均要快 5-8%,但有時也會慢不少;在浮點運算的速度上,x32 較 x86-64 並無優點。html
簡單來講呢,就是爲 x32 編譯的程序,既能得到 64 位系統跑的快的優點,又只使用跟 32 位程序差很少少的內存。若是你的計算機只有 4GB 或更少的內存,但卻擁有一顆強勁的 64 位 CPU 的話,那 x32 將能更大程度地榨取你硬件的潛力。(注,單進程不使用超過 4GB 內存的,理論上也能夠受益於 x32,只是說若是你的筆記本已經在跑 32GB 內存了的話,那估計也不用省這一小半的內存了——再買條 32GB 的內存去吧。)python
警告,x32 ABI 是一個開發中的 Linux 項目,因此碰到一些 bug 是很正常的。筆者假設你已經有一臺運行着 x86_64 ArchLinux 的機器。linux
更新:自從 ArchLinux kernel 3.5.4-1 以後,x32 已是默認開啓的了,內核版本號高於 3.5.4-1 的 ArchLinux 用戶請跳過本步驟。git
OK,能夠着手開始編譯了。是的,咱們要從源碼開始編譯,白手起家。到底多白呢,從 Linux Kernel 開始。Linux Kernel 自 3.4 開始支持 x32 ABI,只須要打開一個內核選項就能夠了:github
CONFIG_X86_X32=y
若是你不想按照 ArchLinux wiki 上的每一步來本身配置編譯你的內核的話,最簡單的辦法就是使用筆者提供的 AUR 包(已刪除)——基於 ArchLinux 官方內核的 x32 版本。因此呢,若是你已經安裝了 yaourt,那麼執行下面的命令就夠了:sql
yaourt -S linux-x32
編譯內核花 1 個小時以上很正常。安裝好以後,你能夠修改你的系統引導文件(/boot/grub/menu.lst
或者其餘引導配置文件),重啓進入新裝的內核。安全
更新:編譯好的二進制包已經上傳至 ArchLinux 中文社區軟件倉庫,若是你想立刻擁有支持 x32 的編譯器的話,能夠直接從那裏安裝,跳過步驟 二、三、4。bash
由於 x32 的 GCC 和 Glibc 有雞生蛋蛋生雞的問題,因此咱們在編譯正式的 x32 GCC 和 Glibc 以前呢,須要先下兩個種子。架構
第一個實際上是一個缺失的頭文件,最終的 x32 Glibc 將會包含這個頭文件,可是在目前須要先用到它的狀況下,咱們能夠暫時作一個軟連接:
sudo ln -s /usr/include/gnu/stubs-64.h /usr/include/gnu/stubs-x32.h
一樣地,筆者已經爲這個軟連接作好了一個 AUR 包,若是你是用的是 ArchLinux,那麼你沒有必要手動建立這個軟連接(還得記着裝完兩個種子以後刪除它)。這個 AUR 包會在安裝正式的 x32 Glibc 的時候自動卸載,刪除無用的軟連接。安裝命令以下:
yaourt -S glibc-x32-seed
第二個種子是一個臨時的 GCC 編譯器,其中一半是咱們即將本身編譯的,另外一半 x32 的庫咱們沒法本身編譯(由於缺乏 x32 的 Glibc),因此要先用別人編譯好的。x32 ABI 須要 GCC 的版本至少爲 4.7。在配置 GCC 的時候,尤爲要注意添加 x32 的支持:
cd gcc-4.7.1 ./configure --with-multilib-list=m32,m64,mx32
而後 make
,數分鐘以後 make
會失敗,由於咱們尚未 x32 的 Glibc。這時候,把下好的 gcc-x32-seed.tar.bz2
解壓到 gcc
文件夾下面就行了。具體的步驟能夠參考這一篇文章,比較省事兒的辦法仍然是繼續用筆者提供的 AUR 包,自動完成下載、編譯和安裝:
yaourt -S gcc-x32-seed
終於要開始編譯正式的 x32 Glibc 了。Glibc 自 2.16 開始支持 x32 ABI,因此若是你沒法使用筆者的 AUR 包的話,你須要先去下載一份 Glibc 的源碼,解壓以後,配置須要一下幾點注意:
指定使用你的 GCC 種子編譯器,且使用 x32 來編譯,好比 CC="/path/to/cc -mx32 -B/path/to/gcc/libs" CXX="/path/to/g++ -mx32 -B/path/to/gcc/libs"
指定正確的環境參數:--target=x86_64-x32-linux --build=x86_64-linux --host=x86_64-x32-linux
啓用多架構支持:--enable-multi-arch
指定與 ArchLinux 習慣一直的 lib
文件夾位置,在 configparms
文件中添加:slibdir=/usr/libx32
而後開始正常的編譯。編譯好了以後,前面作的兩個種子就算圓滿完成任務了,刪掉他們(種子 GCC 並不影響),而後安裝剛編譯好的 Glibc。最後爲了在 ArchLinux 中正常工做,還要作額外的幾步:
sudo ln -s /usr/libx32/ld-linux-x32.so.2 /usr/lib/ld-linux-x32.so.2
建立 /etc/ld.so.conf.d/libx32-glibc.conf
,添加一行 x32 庫的路徑信息:/usr/libx32
軟連接區域信息:sudo ln -s /usr/lib/locale /usr/libx32/locale
最後由於 ArchLinux 官方庫的一個 bug,須要額外一個軟連接:sudo ln -s /usr/lib /libx32
全部這些 x32 Glibc 的工做都包含在了筆者製做的 AUR 包中:
yaourt -S libx32-glibc
注意,安裝這個包會提示與 glibc-x32-seed 衝突,只須要贊成刪除 seed 包就能夠了。
勝利在望,下一步編譯好正式的 x32 GCC 就算有了一個最基本的 x32 編譯工具集。編譯 x32 的 GCC 跟在 ArchLinux 上編譯普通的 gcc-multilib 沒有多大區別,只要把路徑 /usr/libx32
設置正確就能夠了——對了,還有 configure
的時候記着加 x32 支持:
cd gcc-4.7.1 ./configure --with-multilib-list=m32,m64,mx32 ...
照例,筆者提供的 AUR 包以下:
yaourt -S gcc-multilib-x32
裝這個 AUR 包的時候,系統會提示與一大堆包衝突——不要緊,贊成刪掉衝突的 gcc-libs gcc-libs-multilib gcc gcc-x32-seed 是安全的,由於 gcc-multilib-x32 能夠支持編譯 3 種架構的程序:x8六、x86_64 和 x86_x32。
裝好以後,是否是打算試一下 x32 的編譯效果?沒問題,你能夠試試下面這段簡單的 C 程序:
#include <stdio.h> int main() { int i = 0; printf("Size of pointer: %d\n", (int)sizeof(&i)); return 0; }
針對三種不一樣的架構進行編譯:
gcc -m32 test.c -o test_32 gcc -m64 test.c -o test_64 gcc -mx32 test.c -o test_x32
而後執行試一下:
$ ./test_32 Size of pointer: 4 $ ./test_64 Size of pointer: 8 $ ./test_x32 Size of pointer: 4
因爲 Python 依賴的庫還比較多,其中一些如 OpenSSL 還須要額外的補丁才能在 x32 上編譯,筆者在這裏就不一一詳解了,直接用 AUR 包搞定吧:
yaourt -S libx32-readline libx32-libffi libx32-ncurses libx32-expat libx32-bzip2 libx32-gdbm libx32-openssl libx32-sqlite3 libx32-zlib python2-x32
寫個簡單的 Python 程序試一下吧:
import time placeholder = [None] * 1024 * 1024 * 8 time.sleep(600)
而後執行試一下:
python2 test.py & /opt/python2-x32/bin/python2.7 test.py &
打開系統監視器,看看這兩個進程的內存是否是幾乎差了一半?
版本歷史:
2014-2-17:Markdown 版本,增長了更新註釋
2012-7-29:發佈於 http://blog.chinaunix.net/uid/350516.html