Improving dot product for standard multidimensional D arrays
Timon Gehr
timon.gehr at gmx.ch
Wed Mar 4 13:58:05 UTC 2020
On 01.03.20 21:58, p.shkadzko wrote:
>
> ******************************************************************
> Matrix!T matrixDotProduct(T)(Matrix!T m1, Matrix!T m2)
> in
> {
> assert(m1.rows == m2.cols);
This asserts that the result is a square matrix. I think you want
`m1.cols==m2.rows` instead.
> }
> do
> {
> Matrix!T m3 = Matrix!T(m1.rows, m2.cols);
>
> for (int i; i < m1.rows; ++i)
> {
> for (int j; j < m2.cols; ++j)
> {
> for (int k; k < m2.rows; ++k)
> {
> m3.data[toIdx(m3, i, j)] += m1[i, k] * m2[k, j];
> }
> }
> }
> return m3;
> }
> ******************************************************************
> ...
> I can see that accessing the appropriate array member in Matrix.data is
> costly due to toIdx operation but, I can hardly explain why it gets so
> much costly. Maybe there is a better way to do it after all?
Changing the order of the second and third loop probably goes a pretty
long way in terms of cache efficiency:
Matrix!T matrixDotProduct(T)(Matrix!T m1,Matrix!T m2)in{
assert(m1.cols==m2.rows);
}do{
int m=m1.rows,n=m1.cols,p=m2.cols;
Matrix!T m3=Matrix!T(m,p);
foreach(i;0..m) foreach(j;0..n) foreach(k;0..p)
m3.data[i*p+k]+=m1.data[i*n+j]*m2.data[j*p+k];
return m3;
}
(untested.)
More information about the Digitalmars-d-learn
mailing list