Я пытаюсь использовать System.Numerics.Vector (T) для векторизации алгоритма и использования SIMD-операций CPU. Однако моя реализация вектора была значительно медленнее, чем моя первоначальная реализация. Есть ли уловка для использования векторов, которые, возможно, не были документированы? Конкретное использование здесь - попытаться ускорить Xors из kb данных.Использование вектора <T> для SIMD в универсальной платформе Windows
К сожалению, почти вся документация, которую я могу найти на ней, основана на предварительной версии RyuJIT, и я не знаю, сколько из этого материала переносится на .NET Native.
Когда я проверить разборки во время операции Vector исключающего, он показывает:
00007FFB040A9C10 xor eax,eax
00007FFB040A9C12 mov qword ptr [rcx],rax
00007FFB040A9C15 mov qword ptr [rcx+8],rax
00007FFB040A9C19 mov rax,qword ptr [r8]
00007FFB040A9C1C xor rax,qword ptr [rdx]
00007FFB040A9C1F mov qword ptr [rcx],rax
00007FFB040A9C22 mov rax,qword ptr [r8+8]
00007FFB040A9C26 xor rax,qword ptr [rdx+8]
00007FFB040A9C2A mov qword ptr [rcx+8],rax
00007FFB040A9C2E mov rax,rcx
Почему не это использовать регистры XMM и инструкции SIMD для этого? Что также странно, так это то, что инструкции SIMD были сгенерированы для версии этого кода, которую я явно не выделил, но они никогда не исполнялись в пользу обычных регистров и инструкций.
Я гарантировал, что я работал с Release, x64, включен оптимизированный код. Я видел подобное поведение с компиляцией x86. Я немного новичок в аппаратном уровне, поэтому возможно, что здесь что-то происходит, что я не понимаю.
Рамочная версия 4.6, Vector.IsHardwareAcclederated является ложным во время выполнения.
Обновление: «Скомпилировать с. NET-инструментальную цепочку» является виновником. Включение этого вызывает Vector.IsHardwareAccelerated == false; Отключение его вызывает Vector.IsHardwareAccelerated == true. Я подтвердил, что когда .NET Native отключен, компилятор создает инструкции AVX, используя регистры ymm. Что приводит к вопросу ... почему SIMD не включен в .NET Native? И есть ли способ изменить это?
Update Tangent: я обнаружил, что причина автоматического SSE-Векторизованные коды массива не выполняются потому, что компилятор вставил команду, которая выглядела, чтобы увидеть, если начало массива было ниже адрес чем один из последних элементов массива, и если это так, просто используйте обычные регистры. Я думаю, что это должно быть ошибкой в компиляторе, потому что начало массива всегда должно быть на более низком адресе, чем его последние элементы по соглашению. Это было частью набора инструкций, проверяющих адреса памяти каждого из массивов операндов, я думаю, чтобы убедиться, что они не перекрываются. Я подал отчет об ошибке Microsoft Connect для этого: https://connect.microsoft.com/VisualStudio/feedback/details/1831117
Какая версия Framework это? Сообщается, что аппаратное ускорение является «истинным»? – usr
Рамочная версия 4.6, а IsHardwareAccelerated возвращает false. –
«Почему SIMD не включен в .NET Native?» Я могу только догадываться: SIMD обрабатывается JIT (компилятор Just-in-time, тот, который преобразуется во время выполнения IL-кода в собственный код). .NET native полностью обходит JIT, создавая чисто родную сборку (без необходимости перевода). Я предполагаю, что они просто не реализовали поддержку SIMD в основной цепочке инструментов .NET. Либо потому, что у них еще не было времени, либо потому, что родной .NET можно было использовать для создания программ, работающих на процессорах, у которых нет регистров SIMD –