2009-02-04 78 views
4

我正在考慮將C#項目中的一小部分代碼移植到C/ASM中以獲得性能優勢。 (這段代碼使用了許多按位操作,並且是通過使用本機代碼可能會提高性能的少數幾個地方之一。)然後,我打算通過P/Invoke簡單地調用單獨DLL中的本機函數。現在,在託管代碼和本地代碼之間傳遞的唯一數據將是純粹的原始類型(bool,int,long,1D數組等)。所以我的問題是:使用P/invoke簡單地使用基本類型會有什麼顯着的開銷嗎?我知道在使用更復雜的類型時會有一個基本的開銷,因爲它們需要編組(固定/複製),但在我的情況下它可能相對有效(與從本地DLL本身內部調用代碼相比) )?如果有人能爲我澄清這個問題,解釋性能優勢/命中的程度和背後的原因,這將是非常感謝。完成整個任務的另一種方式也是值得歡迎的,儘管由於C#缺乏對內聯彙編/ CIL的支持,我不相信有一個。僅使用原始類型的本地互操作的開銷

回答

5

從MSDN(http://msdn.microsoft.com/en-us/library/aa712982.aspx):

「的PInvoke具有每呼叫10和30之間的x86指令的開銷除此之外固定成本,編組產生額外開銷有Blittable型之間沒有編組成本那個。在託管代碼和非託管代碼中具有相同的表示形式,例如,在int和Int32之間進行轉換沒有任何代價。「

所以,這是相當便宜,但一如既往,你應該仔細測量,以確保你從它受益,並牢記任何維護開銷。順便說一句,我會推薦C/CLI(「託管」C++)來處理任何複雜的互操作,特別是如果你對C++感到滿意的話。

+0

謝謝,我在閱讀文檔時一定錯過了。事實上,我將確定各種實施方式。關於託管C++,你也提出了一個很好的觀點,但是你會否知道通過P/Invoke調用託管C++函數是否比原生函數更便宜? – Noldorin 2009-02-04 11:49:25

+0

只需確認:託管的C++可以包含內聯ASM,對吧?鑑於這種情況,這似乎是更好的解決方案。 – Noldorin 2009-02-04 11:53:07

0

您可以通過在最終用戶的計算機上使用ngen(作爲安裝過程的一部分)來生成.NET程序集的已編譯優化版本。

根據我的經驗,格式正確的C#(例如,保持循環以外的分配)將表現得非常好。

+0

我相信你在絕大多數情況下是正確的。不過,我真的想在這裏使用C/C++來獲得其快速位操作的好處(特別是通過內聯ASM訪問專用x86指令來加速)。無論如何,值得剖析。 – Noldorin 2009-02-04 11:56:44

1

我似乎記得聽說每個P/Invoke調用至少有30個機器操作開銷。但忽略理論,分析你的選擇並選擇最快的。

1

我會親自安裝測試工具寫在C#和非託管C++一個簡單的表達,那麼配置文件中的應用程序,看看你正在使用什麼樣的表現三角洲。

別的東西要考慮的是,你推出一個維護問題與應用程序,特別是如果你有料將維持代碼初中級開發人員。確保你知道你正在獲得什麼,以及你失去了什麼性能以及代碼清晰度和可維護性。另外,JIT'd C#代碼在算術運算方面應該具有與C++相媲美的性能。