AMD64 與 EM64T
雖然超微的 AMD64 並非第一個 64 位元處理器,但卻是第一個廣受市場歡迎的 64 位元處理器。在超微推出 AMD64 系列處理器之前,英特爾(及其他廠商)就已經推出 64 位元的處理器,但是這些 64 位元處理器都是鎖定在伺服器或高階工作站等市場。例如 DEC(Digital Equipment Corp.,後來被康柏併購,而康柏後來也被惠普併購)、IBM、昇陽以及惠普等推出多時的 Alpha、Power、SPARC 和 PA-RISC 處理器都是 64 位元的處理器,而這些處理器大多用在高階的 UNIX 伺服器。
英特爾在 2001 年所推出的 Itanium、以及日後改版的 Itanium2 也是 64 位元處理器架構,而且微軟也曾經為 Itanium 和 Itanium2 推出過 64 位元的 Windows 作業系統,包括 Windows 2000 Workstation 和 Server 版本,以及 Windows XP Professional 和 Windows Server 2003。不過這些昂貴的處理器也是應用在高階的伺服器和工作站。
超微的 AMD64 系列處理器(簡稱 x86-64 或 x64 處理器),雖然也是 64 位元的架構,但是 AMD64 的架構是進化(evolution),而非革命(revolution);AMD64 以 Instruction Set Architecture 技術(指令集架構,ISA)延伸目前 x86 的 32 位元架構,除了可以直接執行 64 位元程式之外,也不用透過模擬器就能執行大多數的 32 位元程式,這是 AMD64 可以和現今絕大多數的 32 位元軟體保持相當優異相容性、甚至提高執行效能的關鍵。
而當超微開始銷售 x64 處理器,並且獲得市場接受之後,英特爾也向超微授權 x64 處理器的技術(也就是 ISA),並且將這項技術以 EM64T(Extended Memory 64 bit Technology)為名,加入旗下 Pentium 4、Celeron、Xeon 等系列處理器,因此這些處理器也都具備與 AMD64 相同的 64 位元運算能力,又能與 x86 32 位元軟體保持絕佳的相容性和效能(在英特爾的文件當中,IA32e 是 EM64T 的另一個同義詞。IA 是 Intel Architecture 的縮寫,32 表示 32 位元,e 是 extension,也就是說這是以32位元延伸而成的架構。另外,IA32 是 32 位元 x86 架構,而 IA64 則是 Itanium/Itanium2 架構)。
x64 處理器的優點
x64 處理器最大的優點,是可以提供更大的記憶體定址空間,以及更佳的浮點數運算效能。32位元x86 處理器最大的記憶體定址空間是 4 GB(2^32),對許多軟體或許這已經足夠,但是對某些必須處理相當大量資料的應用程式而言—尤其是伺服端的軟體,4 GB 卻是造成執行效能的瓶頸,因為當系統無法提供足夠的實體(physical)記憶體空間,就必須轉而使用通常是由硬碟空間提供的虛擬記憶體;存取硬碟的速度遠低於存取實體記憶體的速度。
4 GB 的記憶體上限對 32 位元處理器並非無解,但仍然有其限制。Physical Address Extensions(實體記憶體延伸,PAE)是內建於英特爾處理器的功能,這項功能可以讓應用程式存取 4 GB 以上的實體記憶體,但是這項功能需要作業系統的支援,目前 Windows Server 2003 Enterprise Edition、Windows Advanced Server, Limited Edition、Windows 2000 Datacenter Server、Windows 2000 Advanced Server 等 Windows 作業系統就是利用 PAE 技術而突破 4 GB 的記憶體限制。此外,在設計 Windows 程式時,也必須利用作業系統提供的 Address Windowing Extensions(AWE)功能,讓程式直接存取 4 GB 以上的記憶體。
PAE 和 AWE 是讓 32 位元系統突破 4 GB 記憶體上限的解決技巧,但這些額外的技巧會增加程式設計的困難度,而且因為 PAE 的分頁表還是得放在 4 GB 的記憶體空間,因此當 PAE 超過 16 GB 之後,執行效能也會降低。
為了真正突破 4 GB 的記憶體上限,超微在 AMD64 加入了 40 位元的實體記憶體和 48 位元的虛擬記憶體定址能力,而這項功能讓 x64 處理器可以直接存取超過 4 GB 的記憶體空間。以下的表格則列出了 32 位元和 64 位元 Windows XP Professional 的記憶體存取能力。
記憶體(包含虛擬) |
16 TB |
4 GB |
分頁檔案 |
512 TB |
16 TB |
分頁集區 |
128 GB |
470 MB |
非分頁集區 |
128 GB |
256 MB |
系統快取 |
1 TB |
1 GB |
x64 處理器的另一項優點,是可以簡化組織內的 IT 管理成本,甚至簡化軟體開發成本。對IT人員管理系統或網路來說,管理 Windows x64 與 32 位元 Windows 的方式幾乎完全相同,IT 人員只要使用相同的管理工具,就能將 Windows x64 加入現今的 Windows 網路系統;此外,這更是保障了企業主目前部分的 IT 投資。這些優點源自於 x64 架構是以 x86 延伸而來,如此的作法讓 Windows x64 能夠相容現今的 32 位元 Windows 應用程式。
也因為 x64 處理器與 32 位元軟體有很高的相容性,所以軟體開發商不必然得立即將軟體都移植到 x64 平台,可以先測試 32 位元程式在 Windows x64 環境的相容性,再視情況來決定是否要移植軟體,或者制訂軟體移植的先後順序等策略。再者,由於 x64 處理器採用「站在原本的基礎往外延伸」的設計哲學,提供了一條讓開發人員轉換到 64 位元的捷徑,也大幅簡化了軟體移植到 64 位元的過程。
AMD64 的軟體執行模式
AMD64 提供了兩種軟體執行模式(如圖 1)。Long Mode 需要專屬的 x64 位元作業系統,並且可以執行專屬的 x64 位元應用程式和的 x86 32 位元應用程式;只有專屬的 x64 位元作業系統才能啟用 64 位元的指標、暫存器,並且讓 AMD64 進入 Long Mode。
圖 1:AMD64 的軟體執行模式 (資料來源:超微)
在 Long Mode 又包含了兩種模式,64-bit Mode 提供專屬的 64 位元應用程式運作環境,而 Compatibility Mode(相容模式)則讓專屬的 64 位元作業系統可以執行原本的 32 位元應用程式。
除了 Long Mode,AMD64 還包含了 Legacy Mode(傳統模式),這其實就是原本的 x86 架構,提供了包括 16 位元的真實模式以及 32 位元的虛擬 8086 模式和保護模式。也因為 AMD64 提供了 Legacy Mode,因此原本相容於 x86 的 32 位元 Windows 甚至 DOS 等作業系統,都可以繼續在 x64 處理器運作。
WOW64 子系統
Windows x64 的使用者模式(user mode)有一個 WOW64 子系統(Windows On Windows64,WOW64.DLL,如圖 2),這個子系統將負責 32 位元應用程式與 Windows x64 作業系統之間的溝通:WOW64 子系統會將 32 位元應用程式的系統呼叫轉換成 Windows x64 作業系統的格式,然後再轉給 Windows x64;作業系統會以為這是由 WOW64 子系統所呼叫,而將結果傳給 WOW64,接著 WOW64 會再將 Windows x64 的傳回值轉換成 32 位元的格式,最後再送回當初發出呼叫的 32 位元應用程式。
圖 2:32 位元應用程式與 64 位元應用程式在 64 位元作業系統的運作模式 (資料來源:超微)
請注意,因為 WOW64 子系統位於 Windows x64 的使用者模式,因此 WOW64 只能維繫 32 位元使用者模式程式與 Windows x64 的相容性,必須在核心模式(kernel mode)執行的 32 位元應用程式或驅動程式,都會與 Windows x64 有相容性的問題。
此外,在 Windows x64 當中,32 位元的應用程式不僅有完全與 64 位元程式互相獨立的執行環境(如圖 2),甚至連登錄機碼和軟體安裝的資料夾都各自獨立,以免兩種類型的軟體同時執行而發生衝突。因此程式裡不能混合 32 位元和 64 位元的程式碼;請牢記這點,因為許多軟體相容的問題都是因此而起。當然,個別的 32 位元和 64 位元行程可以透過行程之間的通訊結構(interprocess communications structures)相互傳送資料。而雖然 32 位元應用程式在 64 位元作業系統依然會有 4 GB 的記憶體上限,但是卻可以擁有獨享的記憶體空間,不需要與作業系統核心、分頁表或其他的應用程式共用記憶體空間。
軟體相容性的經驗談
前述討論 x64 架構時,我已經簡略提到若干可能造成軟體相容問題的關鍵,現在我想更詳細說明我的經驗。
Windows 32 On Windows x64
之前我提過 WOW64 子系統,這個子系統可以視為 Windows x64 所虛擬的 32 位元 Windows 執行環境,因此 WOW64 其實是為 "32" 位元程式而設計。此外,在 Windows x64 系統的 WINDOWS 資料夾裡面,SYSTEM32 資料夾也非如其名,這個資料夾實際上是放置 64 位元的系統檔案,SYSWOW64 資料夾才是放置 WOW64 子系統所需要的 32 位元系統檔案。
之所以有這種「32 是 64、64 是 32」的現象,是因為 Windows x64 在載入應用程式之前,並不知道程式是 32 位元還是 64 位元,而當載入並確認應用程式是 32 位元還是 64 位元之後,64 位元的程式就使用 SYSTEM32 資料夾裡的系統檔案,而 32 位元的程式則被 WOW64 子系統導引並使用 SYSWOW64 資料夾裡的系統檔案;但是對 32 位元的程式來說,並不知道被導引到 SYSWOW64 資料夾,還是以為用的是 SYSTEM32 資料夾裡的系統檔案,因此沒有符合 Windows 程式設計規範的 32 位元程式在 Windows x64 執行的時候,可能會因為無法被導引到 SYSWOW64 資料夾,還是繼續並企圖使用 SYSTEM32 資料夾裡的 64 位元系統檔案,就會造成相容性的問題而無法執行。
還有一個類似的情況是安裝軟體的資料夾:Windows x64 有兩個安裝軟體的資料夾,一個是大家熟知的 Program Files,另一個是 Program Files (x86);前者「預設」是供 x64 應用程式使用,後者「預設」是用來存放 32 位元應用程式。如果程式是以微軟規範的方式取得安裝軟體資料夾的位置,例如環境變數或系統 API,就會得到上述預設的位置,不然就會發生 32 位元應用程式安裝到 Program Files 資料夾的結果。
類似的情況也會發生在存取系統的登錄資料庫。Windows x64 有兩個獨立的軟體設定值存放處,x64 應用程式是存放在 HKEY_LOCAL_MACHINE\SOFTWARE\,但是 32 位元應用程式則是存放在 HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node。如果應用程式存取登錄資料庫的方式最終是藉由系統 API 來完成,那麼 WOW64 會將 32 位元應用程式對登錄資料庫的存取,導到 HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node。
此外,WINDOWS 資料夾裡面雖然還有 16 位元系統檔案專用的 SYSTEM 資料夾,但實際上 16 位元的 Windows 軟體無法在 Windows x64 執行,因此這個資料夾通常是空的,就算真的將 16 位元的系統檔案安裝於此,16 位元的 Windows 軟體還是無法在 Windows x64 執行。
圖 3:在Windows XP Professional x64 執行 16 位元 Windows 程式所出現的錯誤訊息
另一類會發生相容性問題的程式,大多是與系統底層較為相關的程式,尤其是需要在核心模式(kernel mode)執行的軟體,都必須升級到 x64 版本,這是因為 WOW64 位於 Windows x64 的使用者模式(user mode),無法處理需要在核心模式執行的軟體。
驅動程式必須在核心模式執行,許多防毒軟體的模組也必須在核心模式執行,這些軟體都得升級到 x64 版本。比較特別的是部分會以驅動程式的方式運作的軟體,例如 Nero 所附的 Image Drive,是以光碟機驅動程式的方式模擬出光碟機,因此 Image Drive 無法在 Windows x64 執行(實際上在 Windows x64 安裝 Nero 之後,根本不會有 Image Drive)。
還有一個常見的狀況是以列印的方式產生文件檔案,例如 Adobe 的阿酷備(Acrobat),就是以列印的方式產生 PDF 檔案,因此這類的軟體都會在系統安裝印表機驅動程式,但是阿酷備所提供的印表機驅動程式是 32 位元,所以 32 位元的阿酷備雖然可以在 Windows x64 執行,但卻因為印表機驅動不是 x64 版本,而無法產生 PDF 文件。實際上因為這些軟體提供的驅動程式都是 32 位元,因此軟體的安裝程式根本無法將驅動程式裝進 Windows x64 系統。
Windows x64 並不允許 x64 應用程式直接呼叫或內含任何 32 位元的程式碼,因為 32 位元應用程式和 x64 應用程式是在兩個獨立的空間執行(如圖 2),這也會導致若干的相容性問題。例如 Windows x64 的檔案總管是 64 位元的應用程式,而像是 WinRAR 等軟體會以 Shell Extension 的方式來增加檔案總管的功能,例如以滑鼠右鈕按下壓縮檔所出現的快顯功能表會包含解壓縮的動作,就是利用 Shell Extension 的方式達成。
檔案總管的 Shell Extension 其實就是 COM 物件,也就是 32 位元程式。因此在 Windows x64 環境,WinRAR 等軟體在檔案總管滑鼠右鈕所加入的功能都不見了。
另一個例子是 x64 版本的 Internet Explorer 和網頁上的 ActiveX 控制項。ActiveX 控制項也是 32 位元的程式,所以也無法與 x64 版本的 Internet Explorer 相互運作。但這麼一來會造成很多網頁無法正常瀏覽,因為網頁上的 Flash 動畫、ASF 影音檔案都必須依賴 ActiveX 控制項來播放,所以在 Windows x64 還保留了 32 位元的 Internet Explorer,就是為了能繼續執行 ActiveX 控制項。
為了確保相容性,當 Windows x64 日漸普及之後,網頁設計者或許該考慮微軟 Windows Update 的作法:連上 Windows Update 網站之後,先檢查 Internet Explorer 的版本,若發現是 64 位元的 Internet Explorer,就以訊息請使用者換成 32 位元的 Internet Explorer(如圖 5)。
圖 5:Windows Update 網站發現是 64 位元的 Internet Explorer 會請使用者換成 32 位元的 Internet Explorer
要執行 .NET 應用程式,系統必須安裝 .NET 執行環境。而在 Windows x64 系統,1.x 版的 .NET 執行環境是在 WOW64 以 32 位元的方式執行,因此,以 Microsoft .NET Framework 1.x 所開發的 .NET 應用程式也是以 32 位元的方式執行。
x64 版本的 .NET 會出現在 .NET 2.0,而且這個版本的 .NET 也同時會有 32 位元的版本。微軟並沒有將 Microsoft .NET Framework 1.x 移植到 x64 版本的計畫,其實是相容性的問題。因為 .NET 1.x 為了達到與 Win32 較大的相容性,允許程式開發人員在 .NET 應用程式直接呼叫 COM,但是對 Windows x64 來說,並不允許 x64 應用程式直接呼叫或內含任何 32 位元的程式碼,因此就算將 Microsoft .NET Framework 1.x 移植到 x64 版本,目前許多 .NET 1.x 應用程式還是無法在 Windows x64 執行。
最妥善的作法,就是讓 .NET 1.x 執行環境和應用程式繼續以 32 位元的方式在 Windows x64 執行,而讓 x64 版本的 .NET 從 2.0 開始。.NET 2.0 針對 x64 的改良還不止於此,.NET 2.0 的編譯程式可以讓程式開發人員針對處理器選擇 32 位元、x64、IA64、或者任何處理器,讓 .NET 應用程式可以適用更多的執行環境。
此外,因為 Windows x64 的 IIS 6 預設是以 64 位元的模式執行,因此無法與 Microsoft .NET Framework 1.x 共同運作,必須透過以下的指令將 IIS 6 切換到 32 位元來執行,才能繼續執行 ASP.NET 1.x 的程式:
cscript %SystemDrive%\inetpub\AdminScripts\adsutil.vbs set w3svc/AppPools/Enable32bitAppOnWin64 1