簡短版本:我想知道是否有可能以及如何最好地利用DLL中的CPU指定 指令?在DLL中使用cpu特定功能有哪些標準技術?
略微更長的版本: 從微軟下載(32位)DLL時,似乎一種尺寸適合所有處理器。
這是否意味着它們嚴格按照最低公分母(即操作系統支持的最低平臺 )構建? 或者是否有一些技術可用於在DLL中導出單個接口,但在後臺使用CPU特定的代碼以獲得最佳性能?如果是這樣,它是如何完成的?
簡短版本:我想知道是否有可能以及如何最好地利用DLL中的CPU指定 指令?在DLL中使用cpu特定功能有哪些標準技術?
略微更長的版本: 從微軟下載(32位)DLL時,似乎一種尺寸適合所有處理器。
這是否意味着它們嚴格按照最低公分母(即操作系統支持的最低平臺 )構建? 或者是否有一些技術可用於在DLL中導出單個接口,但在後臺使用CPU特定的代碼以獲得最佳性能?如果是這樣,它是如何完成的?
我不知道任何標準技術,但如果我不得不做出這樣的事情,我會寫在DllMain中的一些代碼()函數來檢測CPU的類型和填充跳錶函數指針每個功能的CPU優化版本。
當CPU類型未知時,還需要一個最小公分母函數。
您可以在這裏找到註冊表當前CPU信息:
HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\CentralProcessor
該DLL有望在每臺運行WIN32的計算機上運行,因此您一般都堅持使用i386指令集。沒有針對特定指令集公開功能/代碼的官方方法。你必須手工透明地做到這一點。
基本上使用的技術如下: - 確定CPU的功能,如MMX,SSE在運行時 - 如果它們存在,使用它們,如果不是,有後備代碼準備
因爲你不能讓你的編譯器對於除i386以外的任何其他優化,您必須使用內聯彙編器中的特定指令集編寫代碼。我不知道是否有更高級的語言工具包。確定CPU功能是直接的,但也可能需要在彙編程序中完成。
一個簡單的方法來獲得SSE/SSE2優化是隻使用/arch
論據MSVC。我不會擔心回退 - 除非你有一個非常小的應用程序,否則沒有理由支持任何低於此值的任何內容。
http://msdn.microsoft.com/en-us/library/7t5yh4fd.aspx
相信GCC /克++具有等效標誌。
從Microsoft下載的DLL是針對通用x86體系結構的,原因很簡單,它必須適用於所有大量機器。
直到Visual Studio 6.0的時間框架(我不知道它是否已經改變)微軟用來優化其DLL的大小,而不是速度。這是因爲DLL的整體大小的減少比編譯器可以生成的任何其他優化都有更高的性能提升。這是因爲與從沒有CPU等待內存時的加速相比,微型優化的加速將顯着降低。速度的真正提高來自減少I/O或改進基本算法。
只有少數幾個運行在程序核心的關鍵循環可以從微觀優化中受益,僅僅是因爲它們被調用的次數很多。只有大約5-10%的代碼可能屬於這個類別。您可以放心,這樣的關鍵循環已經由Microsoft軟件工程師在彙編程序中進行了優化,達到了某種程度,並且不會讓編譯器找到太多後臺。 (我知道它期望太多,但我希望它們能做到這一點)
正如你所看到的,增加的DLL代碼只會包含其他版本的代碼,這些代碼會針對不同的體系結構進行調整,當大多數代碼很少使用/不會成爲消耗大部分CPU週期的關鍵代碼的一部分。
對於不同的體系結構,英特爾的ICC可以編譯兩次代碼。這樣,你可以吃你的蛋糕,吃它。 (好吧,你會得到兩個蛋糕 - 你的DLL會更大)。甚至MSVC2005也可以用於非常特殊的情況(例如,memcpy()可以使用SSE4)
在不同版本之間切換的方式有很多。一個DLL被加載,因爲加載過程需要它的功能。函數名稱被轉換爲地址。一種解決方案是讓這種查找不僅取決於函數名稱,還取決於處理器功能。另一種方法使用名稱尋址函數在臨時步驟中使用指針表的事實;你可以切換出整個表格。或者你甚至可以在關鍵功能中有一個分支;所以foo()在更快時調用foo__sse4。
您可以使用預處理器魔法爲不同的CPU編譯相同的.C文件(例如賦予函數不同的名稱),然後將不同的.OBJ文件鏈接在一起。不過,您需要一些邏輯來決定調用哪個函數。 – 2009-09-28 14:48:04