在 c# 中构建一个整数数组,每个调用 c++ 或在 c++ 中构建并传递给 c#?
Posted
技术标签:
【中文标题】在 c# 中构建一个整数数组,每个调用 c++ 或在 c++ 中构建并传递给 c#?【英文标题】:Build an array of ints in c# each calling c++ or build in c++ and pass to c#? 【发布时间】:2012-11-18 00:08:54 【问题描述】:我用 C++ 编写了一个函数,让我可以通过一个内在函数利用新的英特尔 RdRand 数字随机数生成器。
__declspec(dllexport) int __stdcall GetRdRand32(PUINT32 pValue)
return _rdrand32_step(pValue);
我已经将它包装起来,以便我可以通过 PInvoke 在 C# 中使用它,它工作正常,如下所示:
[DllImport("CppDynamicLinkLibrary.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int GetRdRand32(out UInt32 str);
我的用例通常可能涉及请求多个随机数,尽管一次可能只有数百个(每个请求者)。我的问题是,无论如何我都在使用 C++,将另一个可以返回随机数的动态数组(或向量)的函数放在一起是否有意义,即与仅对 C++ DLL 进行多次调用相比,这会大大提高性能吗?性能是一个问题,因为这将在一个服务器应用程序上,可能会在类似的时间向许多客户端发送大约 200 个随机数
如果值得做,我会怎么做?我正在考虑以下内容,尽管我的猜测是找到一种将向量导入 C# 的方法很容易成为性能问题?
__declspec(dllexport) void __stdcall vGetRdRand32(std::vector<UINT32> &pArray)
for (std::vector<UINT32>::iterator It = pArray.begin(); It != pArray.end(); It++ )
_rdrand32_step(&(*It));
最后,Marshal.Copy 会比后一种方法更好吗,如果可以的话,谁能指出我正确的方向?
【问题讨论】:
您应该测试您的假设,即一种方式比另一种方式更快。 【参考方案1】:这取决于你需要走多快。为了获得最快的 rdrand 性能,请使用 64 位 rdrands 并使用多个线程进行拉取。 2 线程拉取速度是单线程拉取速度的 2 倍,即使在同一核心上的 2 个超线程上也是如此。
因此,如果您将所有内核上的所有线程设置为 64 位并行拉动,您应该能够接近 800MBytes/s。
这可能与直觉相反,但它源于片上总线上的并行性导致了这种性能特征。
循环中的单个线程在 Ivy Bridge 上可能获得 70MBytes/s。
因此,对于 200 个随机数,调用开销将占主导地位。但是对于几兆字节,如果您希望它尽可能快,则生成线程是值得的。
【讨论】:
【参考方案2】:当然,从单个调用中获取 200 个随机数将比从 200 个不同调用中获取 200 个随机数更快。它甚至可能快很多倍。但很可能你说的是毫秒的差异。所以可能不值得去做。几毫秒的差异会对您的应用程序的整体性能产生显着影响吗?
如果你决定这样做,你可能不想惹vector
,而是想惹UINT32[]
。在 C# 和 C++ 之间编组 vector
充其量是困难的。出于所有实际目的,这是不可能的。
有关如何编组数组的示例,请参阅 Marshaling Different Types of Arrays。
您可能希望在 C# 中分配数组并将其与大小一起传递给 C++ 函数。这样,您不必担心释放内存。如果您让 C++ 代码分配并返回数组,那么 C# 代码将不得不调用 C++ 函数来释放内存。
【讨论】:
优秀的答案。对关于性能的稍微开放式的问题表示歉意;这当然需要测试。你所做的事情给了我很大的方向,让我可以比较。以上是关于在 c# 中构建一个整数数组,每个调用 c++ 或在 c++ 中构建并传递给 c#?的主要内容,如果未能解决你的问题,请参考以下文章