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