2009-02-04 67 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++相媲美的性能。