Собрать массив целых чисел в c #, каждый из которых вызывает c ++, или собрать в c ++ и перейти к c #?

Я написал функцию на C ++, чтобы позволить мне воспользоваться преимуществами нового цифрового генератора случайных чисел Intel RdRand через встроенную функцию.

__declspec(dllexport) int __stdcall GetRdRand32(PUINT32 pValue)
{
return _rdrand32_step(pValue);
}

Я обернул его, чтобы я мог использовать его в C # через PInvoke, и он работает нормально следующим образом:

[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 лучше, чем последний подход, может ли кто-нибудь указать мне правильное направление, если это будет?

0

Решение

Конечно, получение 200 случайных чисел за один звонок будет быстрее, чем получение 200 случайных чисел из 200 разных вызовов. Это может быть даже во много раз быстрее. Но вполне вероятно, что вы говорите с разницей в миллисекунды. Так что это может не стоить делать. Будет ли разница в несколько миллисекунд заметно влиять на общую производительность вашего приложения?

Если вы решили сделать это, вы, вероятно, не хотите связываться с vector, а скорее с UINT32[], Маршалинг vector между C # и C ++ в лучшем случае будет сложно. Для всех практических целей невозможно.

Увидеть Маршалинг различных типов массивов для примеров того, как маршалировать массивы.

Возможно, вы захотите выделить массив в C # и передать его вместе с размером в функцию C ++. Таким образом, вам не нужно беспокоиться об освобождении памяти. Если у вас есть код C ++, выделяющий массив и возвращающий его, то код C # должен будет вызвать функцию C ++ для освобождения памяти.

0

Другие решения

Это скорее зависит от того, как быстро вам нужно идти. Для максимальной производительности rdrand используйте 64-битные rdrands и работайте с несколькими потоками. Протяжка двух нитей в 2 раза быстрее, чем двух ниток на одном и том же ядре.

Таким образом, если вы установите все потоки на всех ядрах, работающих параллельно, на 64 бита, вы сможете приблизиться к 800 МБ / с.

Это может быть нелогичным, но это происходит из-за параллелизма на микросхемах, что приводит к этой характеристике производительности.

Один поток в цикле может получить 70MBytes / s на Ivy Bridge.

Таким образом, для всего 200 случайных чисел будут преобладать накладные расходы. Но для нескольких мегабайт порождающие потоки имеют смысл, если вы хотите, чтобы они были максимально быстрыми.

2

По вопросам рекламы [email protected]