单声道C#/ C ++互操作,优化矩阵乘法 - 由于开销导致的最小增益?

时间:2017-06-07 06:07:01

标签: c# c++ optimization mono pinvoke

我在C#上有一个矩阵结构,在不使用SSE内在函数的情况下实现了乘法运算。由于我此时无法访问代码,因此我将尝试尽可能多地指定详细信息,而不是复制/粘贴定义。如果需要,我可以在早上编辑帖子以包含相关定义。

该结构有16个float定义为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是匹配的C ++结构,其中包含4x vec4 s。

static extern void MatrixMultiply(mat* m1, mat* m2, mat* out) { *out = *m1 * *m2; }

当对计算进行分析时,平均情况下的增益非常小 - 一微秒或两微秒。然而,最坏的情况变得更糟,从使用C#乘法的150us到使用C ++乘法的400us,这使我认为从导出的dll调用函数的开销几乎消除了SSE指令的增益。

由于我对C#的熟悉程度有限,我无法确定发生了什么。难道我做错了什么?在这种特殊情况下,是否有更快的C#/ C ++通信方法?

1 个答案:

答案 0 :(得分:0)

如果Numerics无法提供足够好的解决方案,那么最好的选择是最小化p / Invoke调用。不要为每次乘法调用Multiply(m1, m2, m_out),而是尽可能在C ++端的一次调用中连接矩阵,如下所示:

void MatrixConcat3(m1, m2, m3, m_out);
void MatrixConcat4(m1, m2, m3, m4, m_out);
void MatrixConcat5(m1, m2, m3, m4, m5, m_out);
...

这样可以减少多次通话的开销。