簡體   English   中英

如何優化4x4矩陣乘法?

[英]How to optimize 4x4 matrix multiplication?

我目前正在開發CrossPlatform圖形引擎,性能分析表明我應該優化矩陣乘法。

Y檢查矩陣是否有修改,因此如果沒有更改,我不會更新矩陣,但是無論如何,世界矩陣乘法正在占用大量處理百分比。

有沒有一種方法可以僅使用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;
}

我不做任何FOR檢查,也不做IF,但是我不知道是否有提高性能的方法,或者是否有死胡同。

對於正在尋找這樣的東西的人,使用gnasher答案后,代碼如下:

    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;

您遇到的一個問題是,在任何賦值矩陣[i] [j] = ...時,編譯器都不知道a和b沒有指向this-> matrix,因此它必須假定a和元素b被覆蓋,需要再次閱讀。

如果你只是寫你應該得到一些改善

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

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

等等

閱讀彼得的評論:如果這些矩陣實際上是指向雙精度數組的指針的數組,那絕對是性能的殺手kill。 只是不要這樣做。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM