Использование SSE в C#
В настоящее время я пишу приложение на C#, которое может принести большую пользу от использования SSE, так как относительно небольшой фрагмент кода занимает 90-95% времени выполнения. Сам код также идеально подходит для SSE (так как он основан на матрице и на основе векторов), поэтому я пошел дальше и начал использовать Mono.Simd, и хотя это существенно изменило время выполнения, этого по-прежнему недостаточно. Проблема с Mono.Simd состоит в том, что он имеет только очень старую SSE-инструкцию (в основном из SSE1 и SSE2, я полагаю), что заставляет dotproduct (или скалярный / внутренний продукт), например, занять 3 инструкции, в то время как это может быть реализован с SSE4 только в одной инструкции (и поскольку SSE4 доступен с 2006 года, можно смело предположить, что он есть у каждого современного компьютера). Кроме того, куча других функций вообще не включена (например, получите абсолютное значение каждого числа, что также потребует неуклюжего обходного решения).
У меня вопрос, есть ли другие библиотеки, которые я могу вызвать из моего кода C#, чтобы использовать SSE/SIMD? Также возможно использовать встроенную сборку в C#, так что, очевидно, я также могу использовать C++-код, даже если это приводит к небольшому снижению производительности, но если у кого-то будет относительно простая в использовании библиотека C++ с указанными функциями, это будет приемлемо Похоже.
Заранее благодарю за любую помощь.
2 ответа
Yeppp с открытым исходным кодом! библиотека (автором которой я являюсь) обеспечивает SIMD-оптимизированные функции обработки данных и может использоваться с языками.Net через официальные привязки. Он поддерживает не только SSE, но и более поздние расширения SIMD вплоть до AVX2 от будущих процессоров Intel Haswell. Библиотека автоматически выбирает оптимальную версию для процессора, на котором она работает.
По состоянию на апрель 2013 года Steam Survey сообщает, что только 64% ПК поддерживают SSE4.1. Другими словами, если вы предполагаете поддержку SSE4.1, вы потерпите крах примерно на трети всех потребительских ПК.
Я не знаком с Mono.Simd, но хорошей альтернативой для Windows является DirectXMath, если вам нужно написать подходящую оболочку для C++/CLI. Ни один из них не воспользуется всеми последними инструкциями, но вы можете сравнительно легко дополнить их встроенными инструкциями. Я не уверен, что вы сможете добиться значительно лучше, чем Mono.Simd с этим, хотя.
В C# нет такой вещи, как "встроенная сборка"; если вы хотите использовать C++ или ассемблерный код из C#, вам придется вызывать его через P/Invoke или оболочку C++/CLI. Из двух, C++/CLI имеет меньше накладных расходов.
Тем не менее, если вам нужно оптимизировать чертовски маленький кусочек кода, лучшим вариантом может быть переписать этот кусочек кода полностью на нативном C++.
C# поддерживает довольно много инструкций SIMD/SSE в System.Numerics, который является кросс-платформенным. Dot product - это поддерживаемая инструкция.
Пакет HPCsharp nuget на nuget.org, который я активно разрабатывал в течение последних двух лет, использует эту возможность для ускорения многих алгоритмов. Дайте мне знать, если некоторые полезные алгоритмы могут использовать ускорение через SIMD/SSE и многоядерный.