我正在考慮將C#項目中的一小部分代碼移植到C/ASM中以獲得性能優勢。 (這段代碼使用了許多按位操作,並且是通過使用本機代碼可能會提高性能的少數幾個地方之一。)然後,我打算通過P/Invoke簡單地調用單獨DLL中的本機函數。現在,在託管代碼和本地代碼之間傳遞的唯一數據將是純粹的原始類型(bool,int,long,1D數組等)。所以我的問題是:使用P/invoke簡單地使用基本類型會有什麼顯着的開銷嗎?我知道在使用更復雜的類型時會有一個基本的開銷,因爲它們需要編組(固定/複製),但在我的情況下它可能相對有效(與從本地DLL本身內部調用代碼相比) )?如果有人能爲我澄清這個問題,解釋性能優勢/命中的程度和背後的原因,這將是非常感謝。完成整個任務的另一種方式也是值得歡迎的,儘管由於C#缺乏對內聯彙編/ CIL的支持,我不相信有一個。僅使用原始類型的本地互操作的開銷
回答
從MSDN(http://msdn.microsoft.com/en-us/library/aa712982.aspx):
「的PInvoke具有每呼叫10和30之間的x86指令的開銷除此之外固定成本,編組產生額外開銷有Blittable型之間沒有編組成本那個。在託管代碼和非託管代碼中具有相同的表示形式,例如,在int和Int32之間進行轉換沒有任何代價。「
所以,這是相當便宜,但一如既往,你應該仔細測量,以確保你從它受益,並牢記任何維護開銷。順便說一句,我會推薦C/CLI(「託管」C++)來處理任何複雜的互操作,特別是如果你對C++感到滿意的話。
您可以通過在最終用戶的計算機上使用ngen
(作爲安裝過程的一部分)來生成.NET程序集的已編譯優化版本。
根據我的經驗,格式正確的C#(例如,保持循環以外的分配)將表現得非常好。
我相信你在絕大多數情況下是正確的。不過,我真的想在這裏使用C/C++來獲得其快速位操作的好處(特別是通過內聯ASM訪問專用x86指令來加速)。無論如何,值得剖析。 – Noldorin 2009-02-04 11:56:44
我似乎記得聽說每個P/Invoke調用至少有30個機器操作開銷。但忽略理論,分析你的選擇並選擇最快的。
我會親自安裝測試工具寫在C#和非託管C++一個簡單的表達,那麼配置文件中的應用程序,看看你正在使用什麼樣的表現三角洲。
別的東西要考慮的是,你推出一個維護問題與應用程序,特別是如果你有料將維持代碼初中級開發人員。確保你知道你正在獲得什麼,以及你失去了什麼性能以及代碼清晰度和可維護性。另外,JIT'd C#代碼在算術運算方面應該具有與C++相媲美的性能。
此鏈接提供一些見解:http://www.codeproject.com/Articles/253444/PInvoke-Performance
施加[SuppressUnmanagedCodeSecurity]屬性時還要注意的性能差異。
- 1. Java的原始類型和泛型的相互作用
- 2. Ada派生類型和原始操作
- 3. Scala中的「裝箱」原始類型的開銷
- 4. C++的std ::地圖Intristic類型初始化使用[]操作
- 5. 使用本地http調用的開銷
- 6. 使用泛型類型的COM互操作
- 7. 原始類變量的算術操作
- 8. typedef - 原始類型到原始類型
- 9. 嵌入互操作類型的問題
- 10. Haxe和原生互操作
- 11. 原型中原始類型的行爲
- 12. 調用操作系統的開銷
- 13. 將原始類型應用到原始類型
- 14. 使用互操作
- 15. CUDA和OpenGL互操作類型
- 16. 互操作類型'mshtml.HTMLHeadElementClass'不能嵌入
- 17. 在F#中嵌入互操作類型#
- 18. WCF COM複雜類型互操作
- 19. 無法嵌入互操作類型'Microsoft.Office.Core ...'
- 20. CryptAPI本地互操作與.NET代碼
- 21. Hashtable的原始類型
- 22. C++地圖模板和原始類型
- 23. 使用結構作爲原型的包裝來進行類型檢查的開銷?
- 24. 導出重載操作,但在同一類型的操作僅僅
- 25. Qt on Android C++ to Java與SIGSEGV的無效或原始返回類型的互操作性失敗
- 26. 操作JS原型
- 27. 打開本地通知的操作(iOS)
- 28. 與原始類型
- 29. Bash原始類型
- 30. 通過ClassLoader使用原始類型
謝謝,我在閱讀文檔時一定錯過了。事實上,我將確定各種實施方式。關於託管C++,你也提出了一個很好的觀點,但是你會否知道通過P/Invoke調用託管C++函數是否比原生函數更便宜? – Noldorin 2009-02-04 11:49:25
只需確認:託管的C++可以包含內聯ASM,對吧?鑑於這種情況,這似乎是更好的解決方案。 – Noldorin 2009-02-04 11:53:07