【发布时间】:2017-11-08 08:09:11
【问题描述】:
我在 C# 上有一个矩阵结构,它在不使用 SSE 内在函数的情况下实现了乘法运算。由于此时我无法访问代码,因此我将尝试尽可能多地指定详细信息,而不是复制/粘贴定义。如果需要,我可以在早上编辑帖子以包含相关定义。
该结构有 16 个floats 定义为M11, M12, M13, ..., M43, M44',指定的顺序布局为:[StructLayout(LayoutKind.Sequential)]
使用属性规范声明 C++ 函数
[DllImport("cppCode.dll", EntryPoint = "MatrixMultiply", CallingConvention = CallingConvention::Cdecl]
我正在尝试使用 P/Invoke 调用 C++ 函数以优化乘法。我的问题是关于传递参数。正如 MSDN 上提到的,如果传递的类型不是 blittable,则成本是 10 到 30 个 CPU + 编组周期。
C# 上的函数调用看起来像
MatrixMultiply(ref matrix1, ref matrix2, out matrix_out);
而 C++ 对应方使用 mat* 接收它们,mat 是具有 4x vec4s 的匹配 C++ 结构。
static extern void MatrixMultiply(mat* m1, mat* m2, mat* out) { *out = *m1 * *m2; }
当分析计算时,增益非常小 - 平均情况下是一微秒或两微秒。然而,最坏的情况变得更糟,从 C# 乘法的 150us 到 C++ 乘法的 400us,这让我认为从导出的 dll 调用函数的开销几乎消除了 SSE 指令的增益。
由于我对 C# 的了解有限,我无法确定发生了什么。难道我做错了什么?在这种特殊情况下,是否有更快的 C#/C++ 通信方法?
【问题讨论】:
-
您可以使用来自
System.Numerics.Vectors的类型,它们使用 SIMD。甚至还有一个Matrix4x4类。 -
@cubrr Matarix4x4 class doesn't support SIMD - 我已经检查了反汇编以确保 - 它现在在 Vectors 上。因此,我尝试将 C# 矩阵存储为 4 SIMD:Vec4,并以天真的方式实现了矩阵乘法。还没有时间进行分析(所以我明天肯定会知道它是否更快),但我希望使用与原始实现相同的朴素矩阵乘法获得更好的性能,因为我们将使用 SIMD 寄存器。
-
嗯,这很令人失望
标签: c# c++ optimization mono pinvoke