【问题标题】:Overhead - Calling C++ function from C#开销 - 从 C# 调用 C++ 函数
【发布时间】:2015-07-30 02:57:03
【问题描述】:

我正在从 C# 调用两个 C++ 函数。在大约 100 万次调用的迭代中这样做时,我看到了大约 30% 的开销。

C++ 函数:

EXTERN_C void STDAPICALLTYPE FunctionA(UINT_PTR mathId)
{
    ...
    ...
}

在我的 C# 程序集 dll 中:

[DllImport("CPlusPlus.dll")]
    public static extern void FunctionA([In] IntPtr mathID);

从如下函数调用:

 public static void HelpingFunction([In]UInt64 mathID)
    {
        FunctionA((IntPtr)mathID);
    }

当“HelpingFunction”被调用超过一百万次时,这种实现方式会产生更多开销。

有人可以给我其他想法以减少开销吗?从 C# 程序集中调用 C++ 函数的其他方法是什么?

【问题讨论】:

  • 很难知道如何改进这一点,因为我们看不到FunctionA 的内部。
  • 您也可以考虑在循环周围编写一个 CLI 包装器,这样您的开销就会从“数百万”次调用减少到只有几个。

标签: c# c++ pinvoke marshalling


【解决方案1】:

您可以尝试添加SuppressUnmanagedCodeSecurityAttribute

允许托管代码在没有堆栈遍历的情况下调用非托管代码。

https://msdn.microsoft.com/en-us/library/system.security.suppressunmanagedcodesecurityattribute.aspx

但是在 p/invoke 调用中总是会有固定成本开销:

PInvoke 的开销在 10 到 30 个 x86 指令之间 称呼。除了这个固定成本之外,编组还会产生额外的 高架。 blittable 类型之间没有编组成本 在托管和非托管代码中具有相同的表示。为了 例如,在 int 和 Int32 之间进行转换是免费的。

https://msdn.microsoft.com/en-us/library/ms235282.aspx

【讨论】:

  • 你的意思是在函数“HelpingFunction(..)”定义之上添加[System.Security.SuppressUnmanagedCodeSecurity]?
  • 不,在 DllImport 之上或像这样 [DllImport("CPlusPlus.dll"), System.Security.SuppressUnmanagedCodeSecurity]
猜你喜欢
  • 2015-10-21
  • 1970-01-01
  • 1970-01-01
  • 2018-02-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多