C# 将数据封送到c++; 我的C++头中有一个DLL函数: DLLEXPORT void __stdcall MultiplyQuaternions(double* a, double* b, double* c);

C# 将数据封送到c++; 我的C++头中有一个DLL函数: DLLEXPORT void __stdcall MultiplyQuaternions(double* a, double* b, double* c);,c#,interop,C#,Interop,a和b是两个包含四元数x、y、z和w分量的四元数组。 c是结果四元数 从C++调用时,这个函数运行得非常快。 从C#im中,将函数原型化如下: [DllImport("Intrinsics.dll", EntryPoint = "?MultiplyQuaternions@@YAXPEAN00@Z", ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] private static extern void

a
b
是两个包含四元数x、y、z和w分量的四元数组。
c
是结果四元数

从C++调用时,这个函数运行得非常快。 从C#im中,将函数原型化如下:

[DllImport("Intrinsics.dll", EntryPoint = "?MultiplyQuaternions@@YAXPEAN00@Z", ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
    private static extern void MultiplyQuaternions(double* a, double* b, double* c);
调用如下所示:

fixed (double* q1ptr = q1Vals, q2ptr = q2Vals, resPtr = resVal)
{
    MultiplyQuaternions(q1ptr, q2ptr, resPtr);
}
这很管用,但表演很差劲。从C语言中得出的相同工作量大约是C++的50倍。
我能在这里做什么。任何暗示都将不胜感激。提前谢谢

我将从
[SuppressUnmanagedCodeSecurity]
和相关属性开始。IIUC,默认情况下,当您调用非托管代码时,将执行堆栈遍历,以确保导致该调用的所有内容都有权调用非托管代码。每次对非托管代码进行调用时都会执行此检查,并且可以累加


编辑:我还将研究使用
extern'C'
或其他一些方法来消除名称混乱。查找
多个四元数
比查找
多个四元数容易@@YAXPEAN00@Z
而且您不必担心将来签名格式会发生变化。

是的,这是朝着正确方向迈出的第一步。从50倍的速度下降到15倍左右。当然,我仍然很好奇是否还有更多的事情可以做如果这会产生可测量的差异,那么您的测量不正确。在度量中包含jitting开销是没有用的。基准测试是一门棘手的艺术,请务必使用流行的基准测试Dotnet nuget软件包进行正确的测试。我们将在明天进行测试。谢谢你的提示。我用诊断技术来测量。秒表和计时::HyrScLeC^ ^ ^ C++代码太简单,C++编译器总是内嵌这个函数。当你品吐它的时候,那是不可能发生的。因此,您总是要支付呼叫开销加上pinvoke marshaller开销,两者都不是特别大。但从百分比上看,当函数只需要很少的时间时,它将是很大的。你需要用C#来写这个函数。当然,但我想用Avx看看它能为四元数/矩阵乘法等做些什么。据我所知,这在C#中是不可用的。它是:是的,这是一个使用SIMD的四元数,比我自己的实现(从C#使用时)要快。我想一定有办法进一步提高编组速度吧?为了澄清这个问题:我不是在寻找一个快速的实现。更多的是关于学习方面。内联提示是一个问题。因此,可能性可能是有限的。另一方面,当从C#调用Numerics.Quaternion.Multiply时,它仍然比我自己的simd实现快得多。好吧,你可以问一个问题,一定要显示你的代码。Pinvoke不会把你抓走的那只会被刮掉。