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.)

Reply via email to