Быстрая векторная математика в .NET. Каковы варианты?
Мое программное обеспечение для 3D-графики, написанное на С# с использованием SlimDX, выполняет множество векторных операций с процессором. (В этой конкретной ситуации невозможно разгрузить работу на GPU).
Как сделать мою векторную математику быстрее? До сих пор я нашел следующие подходы:
- Запустите Mono вместо Microsoft.NET, потому что у них есть поддержка SIMD. Не вариант для этого проекта.
- SlimGen, проект, который внедряет высокопроизводительный математический код во время выполнения. К сожалению, проект еще не в состоянии использования.
- Пишите DLL на С++, используя компилятор, который использует инструкции SSE. Взаимодействие с этой DLL с С#.
Есть ли другие возможности для выполнения более быстрой векторной математики в .NET?
Ответы
Ответ 1
Пишите DLL с помощью компилятора Microsoft Visual С++. Используйте стандартный С++ с встроенными функциями SSE и/или OpenMP для тяжелого числового кода с #pragma unmanaged
. Используйте #pragma managed
, чтобы определить чистый API С++/CLI, который может использовать С#.
C++ взаимодействует довольно быстро, чем p/invoke. И С++/CLI - единственный изящный способ обработки как собранной памяти мусора, так и предположений собственных функций (блоки памяти не будут перемещаться).
Возможно, вы обнаружите, что перенос некоторых вызовов OpenGL на С++ и использование выделенных буферов памяти С++ непосредственно для загрузки VBOs и т.д. также дает большой выигрыш в производительности.
Ответ 2
Microsoft только что объявила о поддержке создания векторизованных инструкций в своем .NET Native компиляторе благодаря встроенной оптимизации компилятора на С++ и, что более важно, встроенной поддержке для типов векторов SIMD в самой последней версии их JIT ( "RyuJIT" ). См. Примеры здесь.
Ответ 3
Последние разработки в .NET включают специализированную библиотеку векторных/матричных SIMD, называемую System.Numerics.Vector:
Использование System.Numerics.Vector для графического программирования
Это будет активировано, как только новый компилятор JIT "RyuJIT" будет по умолчанию, предварительный просмотр здесь:
RyuJIT CTP5: приблизиться к доставке и с лучшей поддержкой SIMD
Итак, очень скоро (надеюсь, 2015) у нас будут очень быстрые векторы SIMD в .NET без каких-либо программных накладных расходов.
Ответ 4
Смешивание .NET с собственным кодом. В этом случае вам понадобится один выпуск для x86 и другой для x64. Вы можете видеть Смешанные (собственные и управляемые) сборки [MSDN]
Ответ 5
Если вы настроены писать код сборки на С#, другой вариант - проект NAsmJit, который является портом AsmJit на С#. Я не обновил его, чтобы отразить последние изменения в этом проекте, но большая часть поддержки была вполне пригодна для использования при последней проверке.