1. 程式人生 > >什麼是64位系統以及64為系統對32位的支援和優缺點

什麼是64位系統以及64為系統對32位的支援和優缺點

第一講  什麼是64位系統

截至本課程編寫的時間為止,市場上有兩種受歡迎的64位微處理器體系結構:IA64 和Intel64

  1. IA-64是由 Intel 和HP 合作開發的64位微處理機體系結構。Itanium 和Itanium2 微處理機中就是用了這種體系結構。如想了解更多關於IA-64的資訊,請檢視Itanium
  2. Intel 64 (EM64T / AMD64 / x86-64 / x64)是x86體系的繼承,同時保持向後相容。這種體系結構的名字有不同變型,因而導致了一些疑惑,但是以下這些名字所指的都是同樣的事物:x86-64, AA-64, Hammer Architecture, AMD64, Yamhill Technology, EM64T, IA-32e, Intel 64, x64。 想了解更多為什麼會有這麼多不同的名字,請參看
    文章

你需要了解到IA-64與Intel64是完全不同、不能相互相容的微處理機體系結構。在本文的範圍內,我們僅討論在Windows軟體開發人員中比較受歡迎的Intel64(x64/AMD64)結構。相對應的,當我們說起Windows 作業系統的時候,我們指的對應Intel64體系的64位作業系統。例如,Windows XP Professional x64 Edition, Windows Vista x64, Windows 7 x64。 Intel64所對應的程式設計模型,對於基於64位windows開發的程式設計師來說,簡稱為Win64

Intel 64 體系結構

Intel64 體系結構,在我們看來,就是一個簡單但是非常有效的對於現有的商用x86體系結構的反向相容。Intel64 加入了64位地址定址的內容,同時擴充套件了資源來更好支援高效能的64位程式。陳舊的16位和32位的應用和作業系統,不需要進行額外的修改或者是重新編譯,就可以在64位體系結構上執行。

64位體系結構出現的原因在於應用需要更大的定址空間。這些應用可能是高效能的伺服器,資料管理系統,CAD或者遊戲。這些應用將從64位地址空間和更多地暫存器中得到大量的效能提升。在陳舊的x86系統中,只有少量的暫存器存在,因而限制了計算任務的效能。暫存器數量的增加使得能夠進一步提高應用的效能。

讓我們首先來看一下x64體系的優勢。

l  64位定址空間

l  擴充套件的暫存器組

l  開發者熟悉的命令集

l  可以在64位結構的作業系統上執行32位程式

l  可以直接使用32位作業系統

64位作業系統

基本上所有現在的作業系統都有支援64位體系結構的版本。 例如,Mircosoft就釋出了Windows XP x64。大型的UNIX的開發者也釋出了64位版,例如Linux Debian 3.5 x86-64,但是這不代表著這些系統的全部程式碼是64位的。因為64位系統提供反向相容,有些作業系統和許多應用仍然是32位。因此,64位版的Windows 使用了一個特殊的模型 

WoW64 (Windows-on-Windows 64),這個模型能夠翻譯32位應用的呼叫來使用64位作業系統的資源。

地址空間

雖然64位處理器理論上能夠支援16 Ebytes (2^64)的記憶體空間,Win64現在僅僅支援16Tbytes (2^44)的空間。造成這個現象的原因有一些:現代的處理器僅僅能夠提供1Tbyte (2^40)的物理儲存的定址。這個體系(不是這個硬體部分)可以擴充套件到支援4 Pbytes (2^52)的空間,但是在這種情況下你需要大量的記憶體來儲存分頁表。

除了上述描述的侷限以外,每一種64位Windows版本的上記憶體的大小取決於Mircosoft的商業決定。不同的Windows版本有不同的限制如下表所示。

 

              表1 不同Windows版本所支援的地址空間

Win64 程式設計模型

與Win32類似的,Win64的頁面大小也是4 Kbyte。最靠前的64Kbyte 地址空間是不開放的,所以最低的正確的地址是0x10000。而不像在Win32中,系統的DLL佔據了超過4 Gbyte的空間。

Intel64 的編譯器有一個特性:它們可以用暫存器來更有效率的傳遞引數給函式,而不是使用堆疊。這就使得使用Win64體系的開發人員可以丟棄呼叫約定(calling convention)的概念。在Win32中,你可以使用許多約定,比如__stdcall, __cdecl, __fastcall。在Win64種,只有一個呼叫約定。下面的例子,是來描述4個整型引數是怎樣通過暫存器的。

l  RCX: 第一個引數

l  RDX: 第二個引數

l  R8: 第三個引數

l  R9: 第四個引數

在第四個引數之後的引數通過堆疊來傳遞。如果是要傳遞浮點型的引數,需要使用XMM0-XMM3 暫存器和堆疊。

在呼叫約定方面的區別,使得開發人員不能夠在同一個程式中同時使用64位和32位的內容。用另一句話來說,如果一個應用是通過64位來編譯的,所有的動態連結庫也要是64位。

通過暫存器來傳遞引數,是使得64位程式比32位程式快的一個創新。你可以通過64位的資料結構來取得進一步的效能提升。在下一講中我們將討論這方面的問題。

第二講 64位Windows環境對32位應用的支援

在我們開始討論64位程式前,讓我們談論一下64位Windows系統對32位應用的反向相容。反向相容是通過WoW64中的機制來實現的。

WoW64 (Windows-on-Windows 64-bit) 是Windows作業系統的一個子系統,它使得能夠在64位Windows系統上執行32位應用。

WoW64子系統不支援以下程式:

  1. 為16位作業系統所編譯的程式
  2. 為32位作業系統所編譯的核心(kernel-mode)程式

間接費用

不同處理器體系的WoW64 有一些不同。例如,為Intel Itanium 2 開發的64位Windows版本,使用WoW64來模擬x86 指令。這個模擬比起Intel64 的WoW64體系需要更多資源,因為系統在執行32位程式的時候需要從64位模式轉換到相容模式。

Intel 64 (AMD64 / x64) 上的WoW64 不需要指令模擬。在這個系統上,WoW64子系統僅僅是通過在32位應用和64位Windows API之間新增額外的一層,來模擬32位的環境。在有些地方,這新加的一層可能比較薄,在另一些地方這一層比較厚。平均來說,對於一個程式,你需要期待因為這一個層次所帶來效能上2%的損失。對於有些程式來說,這個數值可能更大。2%可能並不是一個很大的數字,但是你需要銘記在心的是32位程式在64位系統中比它們在32位系統中執行的要慢。

把程式編譯為64位的程式碼,不僅使你避免使用WoW64,同時能使你得到了效能上提升。這個可以通過體系結構上的改變,如更多的通用暫存器來解釋。平均來說,對於一個程式,通過簡單的重新編譯,你可以期待著在效能上有5%-15%的提升。

在64位環境上執行32位程式的好處

因為WoW64,32位程式在64位系統中比它們在32位系統中執行的要慢。但是簡單的32位程式可以從在64位系統上執行獲得一個好處。或許你知道,如果在32位Windows系統選擇“/3gb”, 程式編譯時選擇"/LARGEADDRESSAWARE:YES",它可以分配到最高達3 Gbytes的記憶體空間。同樣的32位程式在64位系統可以分配大最高達4Gbytes的記憶體空間(現實中大約是3.5 Gbytes的記憶體空間)。

重定位

WoW64子系統是通過將呼叫重定位至檔案和暫存器, 從而將32位程式與64位程式分離開來。 這樣使得32位程式不會意外的接觸64程式的資料。例如,一個從"%systemroot%\System32"中呼叫了DLL檔案的32位應用程式,如果不進行隔離,那麼它可能呼叫了一個32位程式無法相容的64位DLL檔案。為了避免這樣的情況發生,WoW64位子系統將進入"%systemroot%\System32"資料夾的呼叫重定位到呼叫"%systemroot%\SysWOW64"資料夾中的檔案。這種重定位使得開發者能避免相容性的問題,因為32位應用程式需要能與它們相容的特殊的DLL檔案。

為什麼32位DLL不能在64位程式中使用? 是否有方式可以避免這種侷限?

現在是不能夠在64位程序中呼叫32位DLL並執行它的程式碼。這種不可行是因為64位系統的設計造成的。所以說是從根本上的不可能。沒有任何技術,也沒有任何文件沒有記錄的方式可以幫助到你。為了做到這個,你必須要裝載並初始化WoW64,更不用說核心結構的不同了。這代表著64位的處理器必須在執行中被處理為32位。這個話題在"Why can't you thunk between 32-bit and 64-bit Windows?". 中有更為詳盡的描述。有一件事情是我建議可以嘗試的,就是建立一個使用COM技術建立一個替代程式, 你可以閱讀"Accessing 32-bit DLLs from 64-bit code".

但是,從32位DLL 將資源匯入到64位程序中去,是比較容易的,你所需要的就是在呼叫LoadLibraryEx 的時候制定以下的flag:LOAD_LIBRARY_AS_DATAFILE。

逐漸放棄對32位程式的支援

微軟公司為了進一步促程序序向64位遷移,會逐漸在一些版本的Windows作業系統中取消對32位程式的支援。這是一個自然的過程。當然這個過程會比較緩慢,但這個行為已經開始了。

許多管理員可能會知道一個較新的作業系統上的伺服器安裝和操作模式,叫做Server Core。 這個模組正是在持久的“Windows VS Linux”大戰中被廣泛提起。 其中一個支援使用Linux的原因就是Linux支援不需要影象介面就可以安裝伺服器操作。 但是,現在Windows Server

也有了這種能力。如果你在這種模式中安裝系統,你將只獲得系統的命令列,而不需要使用者介面。

這種能力(Server Core安裝)出現在Windows Server 2008. 但是在 Windows Server 2008 R2 中,另外一種創新出現使得系統更接近64位。在Windows Server 2008 R2 (Server Core )中,你可以啟動或者禁用系統對32位應用程式的支援。 更重要的是對32位應用程式的支援預設是被禁用的。所以當你嘗試在Server Core mode中啟動32位程式的時候,你會得到一條系統訊息告訴你,這是不可以的。如果你需要額外手動啟用這種支援,可以通過以下命令實現:

start /w ocsetup ServerCore-WOW64

在普通的模式(完全安裝),執行32位程式的支援預設是啟用的。

這種趨勢是十分明顯的,因而現在開始建立64位版本的應用是理智的,因為64位的程式能保證在更多的作業系統版本上使用。

額外資訊

Alexey Pahunov的 Russian blog 也是獲取WoW64資料的好地方。Alexey是Microsoft 的員工,他參與了WoW64子系統的開發。

第三講 將程式碼匯入64位系統的優缺點

你需要帶著以下的問題來學習64位系統:“ 往64位系統重新編譯專案的合理性有多少?”回答這個問題,你需要花費一些時間和精力來思考。在一方面,你可能會因為要提供64位系統的應用支援,使得你在市場上落後於你的對手。 在另一方面,你可能會花費了時間在開發64位系統應用上,而這一努力並不能給你帶來競爭優勢。

以下是一些建議可以用來幫助你做出選擇。

應用的生命期

當你的應用有一個比較短的生命期,你暫時還沒有必要開發應用的64位版本。WoW64子系統使得陳舊的32位應用在64位機上也能取得比較好的表現。如果你在兩年內會停止運營你的產品,你是不需要現在建立一個64位版本的。實踐證明向64位系統的遷移是一個非常緩慢平和的過程。可能你的大多數使用者在未來的一段時間裡還是會僅僅使用你係統的32位版本。你需要知道,本教程是在2009年編寫的,這時候大部分使用者都還是在使用32位系統。但是很快32位程式,就會變得越來越不自然,會變得落伍的。

如果你的專案有一比較長的開發和維護時間,你需要開始建立你產品的64位版本。當然你可以慢慢來,但是你要記住的是,越遲擁有產品的64位版本,在64位系統上維護32 位版本所帶來的問題將越來越多。

程式效能要求

當一個程式重新編譯以適應64位版本後,程式可以應用大量的記憶體資源,它的速度將提高5%-15%。5%-10%的系統提升是因為64位體系結構的特點,如更多的暫存器,所導致的。另外的1%-5%的效能提升是因為拋棄了翻譯32位應用使之在64位系統環境執行的WoW64層所帶來。

例如,Adobe公司稱新版本64位的"Photoshop CS4"比32位版本的快了12%。

需要大量的記憶體的應用可以期待著有更高的效能提升。比如說,影象編輯器,CAD系統,GSI CAD,資料庫和其他的模型包。能將所有的資料儲存在記憶體中,而避免了多餘的從硬碟中匯入的工作,使得這些應用的速度,可能不是提升了幾個百分點,而是成倍的提高。

例如,Alfa-Bank 曾經在他們的IT 基礎設施中使用了基於Itanium 2的平臺。原因在於他們業務的發展使得現有系統無法支援不斷增長的資料量。每個使用者的服務延遲變得非常嚴重。分析顯示,系統的瓶頸不在於處理器的表現,而在於32位體系結構與記憶體子系統的關係上,因為32位體系結構使得只能使用4 Gbyte的伺服器地址空間。而它們的資料庫卻大於9 Gbyte。因而導致了子系統的輸入輸出的臨界負荷。Alfa-Bank決定購買一個由2個伺服器組成的叢集。這兩個伺服器都擁有4處理器、是基於Itanium 2的、擁有12Gbyte記憶體的。 這個決定使得他們的效能要求達到了可以容忍的程度。這個公司的代表稱,引入基於Itanium2 的伺服器使得他們解決了重要問題,同時也節約了花費。

在專案中使用第三方庫

在決定是否開發你產品的64位版本前,請先確認你所依賴的第三方庫是否有64位版本。你需要找出第三方軟體64位版本的定價是多少。這些你都可以在庫開發者的網站上找到。如果,沒有依賴庫的64位版本的支援,可以尋找其他支援64位的庫作為替代。

你所開發的庫的第三方開發者

如果你在開發庫,元件,或者其他需要給第三方開發者使用的程式時,你需要儘快的開發一個你的庫的64位版本。否則需要64位支援的你的客戶會轉向其它的替代產品。例如,一些軟體和硬體安全方面的開發者,都非常遲的開發64位版本,使得他們的一些客戶轉向了其他工具來保護自己的產品。

釋出你所開發庫的64位版本有另一個好處, 你可以把它作為一個單獨模組來出售。因而想要開發32 位和64位的客戶會要購買2個不同的授權。例如Spatial Corporation,就是按這個方式來賣他們的Spatial ACIS庫的。

16位應用

如果你的應用仍然有16位的模組, 你需要丟棄它們。64位的Windows版本完全不支援16位的應用。

關於使用16位安裝程式的人員,我需要解釋一個事情。這樣的安裝程式仍然在被使用於安裝一些32位應用程式。因為對於一些比較流行的16位的安裝程式,它們之中包含了一些機制,使得它們能夠在執行中被更新的32位安裝程式。這可能使得你覺得16位的程式,在64位的系統環境中仍能使用,但這是錯誤的,請牢記。

彙編器程式碼

不要忘記了,大量的彙編器程式碼片是使得建立應用的64位版本更為困難的原因之一。

工具箱

如果考慮以上提到各種因素後,你決定建立一個你的應用的64位版本,成功不是一定的。你還需要一些必要的工具,以下就是一些你可能會碰到的不愉快的事情。

首先最令人不開心的事情,就是缺少64位的編譯器。當我們寫本教程的時候(2009),Embarcadero還沒有64位C++編譯器,它有期望在2009年年底釋出一個。除非你重新編寫你自己的部署部分,如使用Microsoft Visual Studio時可以快速改變配置,否者你沒有辦法迴避這個問題。但其他的問題,就沒有像缺少編譯器這樣,容易被察覺,可能會在你將程式匯入一個新的體系結構的時候發生。你可以在開始工作前,做一個調研,看所有需要的元件是否都有64位版本可以使用。不然,你將面臨不愉快的事情。

做決定時,還需要注意到一個我們還沒提到的問題,修改你的程式碼使之可以在64位模式下編譯所需要的花銷。我們會在之後的課程裡,告訴你怎樣估計這個花銷。這個花銷可能是非常高昂的,需要經過系統的計劃和詳細的時間安排。