2015-05-14 124 views
1

我目前正在開發一個CrossPlatform圖形引擎,性能分析說我應該優化矩陣乘法。如何優化4x4矩陣乘法?

是檢查矩陣的修改,所以我不更新矩陣,如果沒有變化,但無論如何,世界矩陣乘法使用大量的處理百分比。

有沒有辦法更快地使用C++語言技巧?

GRPMATRIX* GRPMATRIX::GetMulplicationMatrix(GRPMATRIX* a, GRPMATRIX* b) 
{   
matrix[0][0] = a->matrix[0][0]*b->matrix[0][0]+a->matrix[1][0]*b->matrix[0][1]+a->matrix[2][0]*b->matrix[0][2]+a->matrix[3][0]*b->matrix[0][3]; 

matrix[0][1] = a->matrix[0][1]*b->matrix[0][0]+a->matrix[1][1]*b->matrix[0][1]+a->matrix[2][1]*b->matrix[0][2]+a->matrix[3][1]*b->matrix[0][3]; 
matrix[0][2] = a->matrix[0][2]*b->matrix[0][0]+a->matrix[1][2]*b->matrix[0][1]+a->matrix[2][2]*b->matrix[0][2]+a->matrix[3][2]*b->matrix[0][3]; 
matrix[0][3] = a->matrix[0][3]*b->matrix[0][0]+a->matrix[1][3]*b->matrix[0][1]+a->matrix[2][3]*b->matrix[0][2]+a->matrix[3][3]*b->matrix[0][3]; 

matrix[1][0] = a->matrix[0][0]*b->matrix[1][0]+a->matrix[1][0]*b->matrix[1][1]+a->matrix[2][0]*b->matrix[1][2]+a->matrix[3][0]*b->matrix[1][3]; 
matrix[1][1] = a->matrix[0][1]*b->matrix[1][0]+a->matrix[1][1]*b->matrix[1][1]+a->matrix[2][1]*b->matrix[1][2]+a->matrix[3][1]*b->matrix[1][3]; 
matrix[1][2] = a->matrix[0][2]*b->matrix[1][0]+a->matrix[1][2]*b->matrix[1][1]+a->matrix[2][2]*b->matrix[1][2]+a->matrix[3][2]*b->matrix[1][3]; 
matrix[1][3] = a->matrix[0][3]*b->matrix[1][0]+a->matrix[1][3]*b->matrix[1][1]+a->matrix[2][3]*b->matrix[1][2]+a->matrix[3][3]*b->matrix[1][3]; 

matrix[2][0] = a->matrix[0][0]*b->matrix[2][0]+a->matrix[1][0]*b->matrix[2][1]+a->matrix[2][0]*b->matrix[2][2]+a->matrix[3][0]*b->matrix[2][3]; 
matrix[2][1] = a->matrix[0][1]*b->matrix[2][0]+a->matrix[1][1]*b->matrix[2][1]+a->matrix[2][1]*b->matrix[2][2]+a->matrix[3][1]*b->matrix[2][3]; 
matrix[2][2] = a->matrix[0][2]*b->matrix[2][0]+a->matrix[1][2]*b->matrix[2][1]+a->matrix[2][2]*b->matrix[2][2]+a->matrix[3][2]*b->matrix[2][3]; 
matrix[2][3] = a->matrix[0][3]*b->matrix[2][0]+a->matrix[1][3]*b->matrix[2][1]+a->matrix[2][3]*b->matrix[2][2]+a->matrix[3][3]*b->matrix[2][3]; 

matrix[3][0] = a->matrix[0][0]*b->matrix[3][0]+a->matrix[1][0]*b->matrix[3][1]+a->matrix[2][0]*b->matrix[3][2]+a->matrix[3][0]*b->matrix[3][3]; 
matrix[3][1] = a->matrix[0][1]*b->matrix[3][0]+a->matrix[1][1]*b->matrix[3][1]+a->matrix[2][1]*b->matrix[3][2]+a->matrix[3][1]*b->matrix[3][3]; 
matrix[3][2] = a->matrix[0][2]*b->matrix[3][0]+a->matrix[1][2]*b->matrix[3][1]+a->matrix[2][2]*b->matrix[3][2]+a->matrix[3][2]*b->matrix[3][3]; 
matrix[3][3] = a->matrix[0][3]*b->matrix[3][0]+a->matrix[1][3]*b->matrix[3][1]+a->matrix[2][3]*b->matrix[3][2]+a->matrix[3][3]*b->matrix[3][3]; 

return this; 
} 

我沒有做任何支票,沒有如果任何一個,但我不知道是否有可能是提高性能的方式或有一個死衚衕。

對於任何人誰是尋找這樣的事情,用咬人的答案後,代碼如下:

float a00=a->matrix[0][0]; 
float a01=a->matrix[0][1]; 
float a02=a->matrix[0][2]; 
float a03=a->matrix[0][3]; 

float a10=a->matrix[1][0]; 
float a11=a->matrix[1][1]; 
float a12=a->matrix[1][2]; 
float a13=a->matrix[1][3]; 

float a20=a->matrix[2][0]; 
float a21=a->matrix[2][1]; 
float a22=a->matrix[2][2]; 
float a23=a->matrix[2][3]; 

float a30=a->matrix[3][0]; 
float a31=a->matrix[3][1]; 
float a32=a->matrix[3][2]; 
float a33=a->matrix[3][3]; 

float b00=b->matrix[0][0]; 
float b01=b->matrix[0][1]; 
float b02=b->matrix[0][2]; 
float b03=b->matrix[0][3]; 

float b10=b->matrix[1][0]; 
float b11=b->matrix[1][1]; 
float b12=b->matrix[1][2]; 
float b13=b->matrix[1][3]; 

float b20=b->matrix[2][0]; 
float b21=b->matrix[2][1]; 
float b22=b->matrix[2][2]; 
float b23=b->matrix[2][3]; 

float b30=b->matrix[3][0]; 
float b31=b->matrix[3][1]; 
float b32=b->matrix[3][2]; 
float b33=b->matrix[3][3]; 

matrix[0][0] = a00*b00+a10*b01+a20*b02+a30*b03; 
matrix[0][1] = a01*b00+a11*b01+a21*b02+a31*b03; 
matrix[0][2] = a02*b00+a12*b01+a22*b02+a32*b03; 
matrix[0][3] = a03*b00+a13*b01+a23*b02+a33*b03; 

matrix[1][0] = a00*b10+a10*b11+a20*b12+a30*b13; 
matrix[1][1] = a01*b10+a11*b11+a21*b12+a31*b13; 
matrix[1][2] = a02*b10+a12*b11+a22*b12+a32*b13; 
matrix[1][3] = a03*b10+a13*b11+a23*b12+a33*b13; 

matrix[2][0] = a00*b20+a10*b21+a20*b22+a30*b23; 
matrix[2][1] = a01*b20+a11*b21+a21*b22+a31*b23; 
matrix[2][2] = a02*b20+a12*b21+a22*b22+a32*b23; 
matrix[2][3] = a03*b20+a13*b21+a23*b22+a33*b23; 

matrix[3][0] = a00*b30+a10*b31+a20*b32+a30*b33; 
matrix[3][1] = a01*b30+a11*b31+a21*b32+a31*b33; 
matrix[3][2] = a02*b30+a12*b31+a22*b32+a32*b33; 
matrix[3][3] = a03*b30+a13*b31+a23*b32+a33*b33; 
+2

使其更快,使用SSE2/AVX或其他SIMD解決方案http://stackoverflow.com/q/14967969/995714 http://stackoverflow.com/q/6617688/995714 http://stackoverflow.com/ q/19806222/995714 ...如果你需要做很多次乘法,那麼多線程也有助於我跨平臺,(pc,android,rpi) –

+0

,不過謝謝 –

+0

http://en.wikipedia.org/ wiki/Strassen_algorithm –

回答

2

一個問題,你必須是在任意分配矩陣[i] [j] =。 ..,編譯器不知道a和b不指向this->矩陣,所以它必須假定a和b的元素被覆蓋並需要再次讀取它們。

你應該得到一定的改善,如果你只是寫

B0 = B->矩陣[0] [0]; b1 = b->矩陣[0] [1]; ... matrix [0] [0] = ...

b0 = b-> matrix [1] [0]; b1 = b->矩陣[1] [1]; ... 矩陣[1] [0] = ...

讀彼得的評論:如果這些矩陣實際上指針雙打的數組的數組,這是一個絕對性能殺手。只是不要這樣做。

+0

你說得對。實際上,我會在例程中使用本地4x4矩陣,並在退出之前將其複製出來。 –

+1

太棒了!這樣做提高了40%! 我在348毫秒內做了4000000個Mults,現在是209毫秒:D –

+1

並且不,它們不是數組數組,它​​是普通的浮點數m [4] [4]。 –