ПрограммированиеФорумГрафика

Перемножение матриц( почему-то D3DXMatrixMultiply все-равно быстрее?!)

Страницы: 1 2 3 4 5 6 7 Следующая »
#0
13:37, 5 фев 2010

День добрый.

Бьюсь с перемножением матриц, но стандартный метод D3DXMatrixMultiply все-равно оказывается быстрее( в коем-то веке )!

Мои реализации перемножения:

#1

_11 = (_11*_mat._11) + (_12*_mat._21) + (_13*_mat._31)+ (_14*_mat._31);
_12 = (_11*_mat._12) + (_12*_mat._22) + (_13*_mat._32)+ (_14*_mat._32);
_13 = (_11*_mat._13) + (_12*_mat._23) + (_13*_mat._33)+ (_14*_mat._33);
_14 = (_11*_mat._14) + (_12*_mat._24) + (_13*_mat._34)+ (_14*_mat._34);

_21 = (_21*_mat._11) + (_22*_mat._21) + (_23*_mat._31)+ (_24*_mat._31);
_22 = (_21*_mat._12) + (_22*_mat._22) + (_23*_mat._32)+ (_24*_mat._32);
_23 = (_21*_mat._13) + (_22*_mat._23) + (_23*_mat._33)+ (_24*_mat._33);
_24 = (_21*_mat._14) + (_22*_mat._24) + (_23*_mat._34)+ (_24*_mat._34);

_31 = (_31*_mat._11) + (_32*_mat._21) + (_33*_mat._31)+ (_34*_mat._31);
_32 = (_31*_mat._12) + (_32*_mat._22) + (_33*_mat._32)+ (_34*_mat._32);
_33 = (_31*_mat._13) + (_32*_mat._23) + (_33*_mat._33)+ (_34*_mat._33);
_34 = (_31*_mat._14) + (_32*_mat._24) + (_33*_mat._34)+ (_34*_mat._34);

_41 = (_41*_mat._11) + (_42*_mat._21) + (_43*_mat._31)+ (_44*_mat._31);
_42 = (_41*_mat._12) + (_42*_mat._22) + (_43*_mat._32)+ (_44*_mat._32);
_43 = (_41*_mat._13) + (_42*_mat._23) + (_43*_mat._33)+ (_44*_mat._33);
_44 = (_41*_mat._14) + (_42*_mat._24) + (_43*_mat._34)+ (_44*_mat._34);

#2

      matrix4x4 out;

      int i,j,k;
    
      for (i=0; i<4; i++)
      {
       for (j=0; j<4; j++)
       {
        out.m[i][j] = m[i][0] * _mat.m[0][j] + m[i][1] * _mat.m[1][j] + m[i][2] * _mat.m[2][j] + m[i][3] * _mat.m[3][j];
       }
      }
      return out;

Еще куча алгоритмов, в том числе и с использованием SSE, но переплюнуть стандартную DX функцию не удается( да и сделать хотя бы равную производительность тоже)!

Поделитесь своими соображениями по этому поводу, или может быть методами?!)

#1
13:51, 5 фев 2010

Исходник от ДХ

D3DX10INLINE D3DXMATRIX
D3DXMATRIX::operator + ( CONST D3DXMATRIX& mat ) const
{
    return D3DXMATRIX(_11 + mat._11, _12 + mat._12, _13 + mat._13, _14 + mat._14,
                      _21 + mat._21, _22 + mat._22, _23 + mat._23, _24 + mat._24,
                      _31 + mat._31, _32 + mat._32, _33 + mat._33, _34 + mat._34,
                      _41 + mat._41, _42 + mat._42, _43 + mat._43, _44 + mat._44);
}

не оно?

#2
13:52, 5 фев 2010

fzr125
Это сложение

#3
13:55, 5 фев 2010

Necrys
Монитор севший нифига не видо ((( ща пороюсь

#4
13:58, 5 фев 2010

у ДХ вот

D3DX10INLINE D3DXMATRIX
D3DXMATRIX::operator * ( CONST D3DXMATRIX& mat ) const
{
    D3DXMATRIX matT;
    D3DXMatrixMultiply(&matT, this, &mat);
    return matT;
}

Здесь пресловутая D3DXMatrixMultiply остается так и не известной

в wine она описывается как:

+D3DXMATRIX* WINAPI D3DXMatrixMultiply(D3DXMATRIX *pout, CONST D3DXMATRIX *pm1, CONST D3DXMATRIX *pm2)
+{
+    int i,j;
+
+    for (i=0; i<4; i++)
+    {
+     for (j=0; j<4; j++)
+     {
+      pout->m[i][j] = pm1->m[i][0] * pm2->m[0][j] + pm1->m[i][1] * pm2->m[1][j] + pm1->m[i][2] * pm2->m[2][j] + pm1->m[i][3] * pm2->m[3][j];
+     }
+    }
+    return pout;
+}

но, опять же, это медленнее чем оригинальная функция

#5
14:01, 5 фев 2010

там SSE2 используется, поэтому и быстрее.

#6
14:04, 5 фев 2010

SSE не даёт прироста на таких мелочах, даже иногда вредит. Рулед инлайн и кэш-френдли методы, можно эффективно на чистом asm без sse написать и то лучче будет.

#7
14:08, 5 фев 2010

Adler
честно говоря - сомневаюсь в этом!

Necrys
да на SSE не особый прирост!
А на счет асемблера, это уже круто! =)


P.s. тут(http://www.gamedev.ru/code/forum/?id=87885) упоминалось, что на форуме кто-то уже делал функцию mul4x4 на SSE с хорошей производительностью, но вот видимо пост уже стерли( ибо не могу найти саму реализацию функции ) =\

#8
14:21, 5 фев 2010

FearOfTheDark
> #1
по моему тут не правильная формула... результат затирает одну из исходных матриц...

#9
14:26, 5 фев 2010

http://www.gamedev.ru/code/articles/?id=4238 - тут вроде бы на SSE оптимизировано делали.

#10
14:28, 5 фев 2010

Pushkoff
затирает, но не в этом суть. методов уже куча опробована,в се уступают ДХ

сейчас попробовал еще как у Alex-y

    r1 =  _mm_mul_ps(_mm_shuffle_ps( A._L1, A._L1, 0x00 ) , B._L1);
    r2 =  _mm_mul_ps(_mm_shuffle_ps( A._L2, A._L2, 0x00 ) , B._L1);
    r1 =_mm_add_ps(r1, _mm_mul_ps(_mm_shuffle_ps( A._L1, A._L1, 0x55 ) , B._L2));
    r2 =_mm_add_ps(r2, _mm_mul_ps(_mm_shuffle_ps( A._L2, A._L2, 0x55 ) , B._L2));
    r1 =_mm_add_ps(r1, _mm_mul_ps(_mm_shuffle_ps( A._L1, A._L1, 0xAA ) , B._L3));
    r2 =_mm_add_ps(r2, _mm_mul_ps(_mm_shuffle_ps( A._L2, A._L2, 0xAA ) , B._L3));
    r1 =_mm_add_ps(r1, _mm_mul_ps(_mm_shuffle_ps( A._L1, A._L1, 0xFF ) , B._L4));
    r2 =_mm_add_ps(r1, _mm_mul_ps(_mm_shuffle_ps( A._L2, A._L2, 0xFF ) , B._L4));
    res._L1 = r1;
    res._L2 = r2;

    r1 =  _mm_mul_ps(_mm_shuffle_ps( A._L3, A._L3, 0x00 ) , B._L1);
    r2 =  _mm_mul_ps(_mm_shuffle_ps( A._L4, A._L4, 0x00 ) , B._L1);
    r1 =_mm_add_ps(r1, _mm_mul_ps(_mm_shuffle_ps( A._L3, A._L3, 0x55 ) , B._L2));
    r2 =_mm_add_ps(r2, _mm_mul_ps(_mm_shuffle_ps( A._L4, A._L4, 0x55 ) , B._L2));
    r1 =_mm_add_ps(r1, _mm_mul_ps(_mm_shuffle_ps( A._L3, A._L3, 0xAA ) , B._L3));
    r2 =_mm_add_ps(r2, _mm_mul_ps(_mm_shuffle_ps( A._L4, A._L4, 0xAA ) , B._L3));
    r1 =_mm_add_ps(r1, _mm_mul_ps(_mm_shuffle_ps( A._L3, A._L3, 0xFF ) , B._L4));
    r2 =_mm_add_ps(r2, _mm_mul_ps(_mm_shuffle_ps( A._L4, A._L4, 0xFF ) , B._L4));
    res._L3 = r1;
    res._L4 = r2;

и опять, DX, на 30% быстрее!

#11
14:39, 5 фев 2010

Самое главное, что в общей массе, ты не выиграешь на этом при написании движка/игры, уже сотни раз тут головы об это били, оптимайзить надо там где тормозит, тут +- ничего не потеряешь, если конечно тысячами скелетку на ЦПУ не считать.

#12
15:22, 5 фев 2010

Оптимизировал (не до конца) xna math перемножение матриц, вышло следующее:

Цикл 255 раз
0.000015365 (сек) - d3dx
0.000015924 (сек) - xna (Optimized)

Если ещё посидеть над оптимизацией, спокойно обойти можно д3дх :)

#13
15:24, 5 фев 2010

Adler
> там SSE2 используется, поэтому и быстрее.
в зависимости от проца, если есть поддержка 3DNow!!! то используется его инструкции а не SSE.

#14
16:47, 5 фев 2010

В майкрософт не дураки сидят.  Вчера спрашивал про аналогичное : "Кто-нибудь сделал перемножение М4х4 быстрее , чем D3DX ?"    Ответа  не последовало.  Хотя перемножение матриц  - это не узкое место.

Страницы: 1 2 3 4 5 6 7 Следующая »
ПрограммированиеФорумГрафика

Тема в архиве.