代码之家  ›  专栏  ›  技术社区  ›  Noldorin

仅使用基元类型的本机互操作的开销

  •  4
  • Noldorin  · 技术社区  · 17 年前

    我正在考虑将我的C项目中的一小部分代码移植到C/ASM,以提高性能。(这段代码使用了许多位操作,并且是少数几个使用本机代码可能会真正提高性能的地方之一。)然后我计划通过p/invoke简单地调用单独的dll中的本机函数。现在,在托管代码和本机代码之间传递的唯一数据将是纯基元类型(bool、int、long、1d数组等)。所以我的问题是:简单地将p/invoke与基元类型一起使用会有什么显著的开销吗?我知道在使用更复杂的类型时会有一个子空间开销,因为它们需要进行编组(固定/复制),但在我的情况下,可能会相对高效(甚至比从本机dll内部调用代码更有效)?如果有人能为我澄清这一问题,解释绩效优势/命中率的程度以及背后的原因,我将不胜感激。另一种完成整个任务的方法也很受欢迎,尽管C缺乏对内联汇编/CIL的支持,我不认为有这样一种方法。

    5 回复  |  直到 12 年前
        1
  •  5
  •   Jim Arnold    17 年前

    来自MSDN http://msdn.microsoft.com/en-us/library/aa712982.aspx ):

    “每次调用pinvoke的开销在10到30个x86指令之间。除此固定成本外,编组还会产生额外的开销。在托管代码和非托管代码中具有相同表示形式的可延迟类型之间没有封送处理成本。例如,在int和int32之间转换没有成本。”

    所以,它是相当便宜的,但像往常一样,你应该仔细测量,以确保你受益于它,并记住任何维护开销。除此之外,我建议在任何复杂的互操作上,通过P/Unjk推荐C++/CLI(“托管”C++),特别是如果您对C++感到满意的话。

        2
  •  1
  •   Scott Weinstein    17 年前

    我似乎记得听说每个P/Invoke调用至少有30个机器操作开销。但是忽略这个理论,分析你的选择,选择最快的。

        3
  •  1
  •   Ryan Emerle    17 年前

    我会亲自用C语言和非托管C++编写一个简单的测试工具,然后对应用程序进行配置,看看你正在使用什么样的性能增量。

    另一个需要考虑的问题是,您将在应用程序中引入一个维护问题,特别是如果您有希望维护代码的初级开发人员。确保您知道自己获得了什么,以及在性能、代码清晰性和可维护性方面分别损失了什么。

    另一方面,JIT C代码应该具有与C++有关算术运算的性能。

        4
  •  0
  •   Nick    17 年前

    您可以通过使用 ngen 在最终用户的计算机上(作为安装过程的一部分)。

    根据我的经验,正确格式化的C(例如,将分配保持在循环之外)将非常好地执行。

        5
  •  0
  •   vent    12 年前

    此链接提供了一些见解: http://www.codeproject.com/Articles/253444/PInvoke-Performance

    还要注意应用[SuppressUnmanagedCodeSecurity]属性时的性能差异。