понедельник, 9 марта 2015 г.

XNAMath

На днях ради фана имплементил софтверный скиннинг моделей на CPU (на GPU проще). Для этого пришлось поглубже залезть в исходники XNAMath, которую использую вместо старой самописной мат. библиотеки.

Оказалось, что скиннинг можно ускорить, если не привязываться к SSE2, который для XNAMath в минимальных требованиях, а использовать дополнительные инструкции из SSE4 и относительно нового AVX. Давненько я не лазил по интринсикам :) А зря, там появилось много вкусненького! Такие функции как XMVector3Transform, XMVector3TransformNormal и XMMatrixMultiply могут быть ускорены использованием _mm_fmadd_ps (fused multiply-add) из AVX. _mm_dp_ps, который появился аж в 4(!) инкарнации SSE (AOS вместо SOA), можно использовать в функциях нормализации и поиска длины вектора. Если надо поточно конвертировать float->half и обратно, скажем, для замапленного буфера вершин, то можно использовать _mm_cvtps_ph и _mm_cvtph_ps из AVX, а не привязываться к софтверной реализации в XMConvertFloatToHalf. Также часто бывает что по ходу мат. вычислений нужно вставить/извлечь какой-нить float в/из XMVECTOR, и для этого есть удобные _mm_insert_ps/_mm_extract_ps. Наконец, добило меня то, что XMVector3Cross написана на SSE2 неоптимально, и можно обойтись только тремя шаффлами. После этого я решил дописать к XNAMath расширение с собственными функциями и предпочтительно использовать их, а саму библиотеку оставить как базу для всего остального, некритичного к производительности.

Ссылки:

DirectXMath: SSE4.1 and SSE4.2
DirectXMath: F16C and FMA
DirectXMath: AVX
Vector Cross Product using SSE Code

P.S.
Из забавного оказалось, что AMD подогнали собственный набор команд SSE вроде multiply-accumulate и  horizontal add/sub, которые, конечно, опять никто не будет использовать (как было с 3DNow!) Update : похоже, эти инструкции будут удалены из архитектуры Zen, как бесперспективные.