0

我用 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 会比后一种方法更好吗,如果可以的话,谁能指出我正确的方向?

4

2 回答 2

2

这取决于你需要走多快。为了获得最快的 rdrand 性能,请使用 64 位 rdrands 并使用多个线程进行拉取。2 线程拉动速度是单线程拉动速度的 2 倍,即使在同一核心上的 2 个超线程上也是如此。

因此,如果您将所有内核上的所有线程设置为 64 位并行拉动,您应该能够接近 800MBytes/s。

这可能与直觉相反,但它源于导致此性能特征的片上总线上的并行性。

循环中的单个线程在 Ivy Bridge 上可能会获得 70MBytes/s。

因此,对于 200 个随机数,调用开销将占主导地位。但是对于几兆字节,如果您希望它尽可能快,则生成线程是值得的。

于 2013-01-26T06:50:19.110 回答
0

当然,从单个调用中获取 200 个随机数将比从 200 个不同调用中获取 200 个随机数更快。它甚至可能快很多倍。但很可能你说的是毫秒的差异。所以可能不值得去做。几毫秒的差异会对应用程序的整体性能产生显着影响吗?

如果您决定这样做,您可能不想弄乱vector,而是想弄乱UINT32[]. 在 C# 和 C++ 之间编组 avector充其量是困难的。出于所有实际目的,不可能。

有关如何编组数组的示例,请参阅编组不同类型的数组。

您可能希望在 C# 中分配数组并将其与大小一起传递给 C++ 函数。这样,您不必担心释放内存。如果您让 C++ 代码分配数组并返回它,那么 C# 代码将不得不调用 C++ 函数来释放内存。

于 2012-11-18T03:52:28.553 回答