Improving dot product for standard multidimensional D arrays

p.shkadzko p.shkadzko at gmail.com
Mon Mar 2 23:17:39 UTC 2020


On Monday, 2 March 2020 at 20:56:50 UTC, jmh530 wrote:
> On Monday, 2 March 2020 at 20:22:55 UTC, p.shkadzko wrote:
>> [snip]
>>
>> Interesting growth of processing time. Could it be GC?
>>
>> +------------------+-------------+
>> | matrixDotProduct | time (sec.) |
>> +------------------+-------------+
>> | 2x[100 x 100]    |        0.01 |
>> | 2x[1000 x 1000]  |        2.21 |
>> | 2x[1500 x 1000]  |         5.6 |
>> | 2x[1500 x 1500]  |        9.28 |
>> | 2x[2000 x 2000]  |       44.59 |
>> | 2x[2100 x 2100]  |       55.13 |
>> +------------------+-------------+
>
> Your matrixDotProduct creates a new Matrix and then returns it. 
> When you look at the Matrix struct, it is basically building 
> upon D's GC-backed slices. So yes, you are using the GC here.
>
> You could try creating the output matrices outside of the 
> matrixDotProduct function and then pass them by pointer or 
> reference into the function if you want to profile just the 
> calculation.

I tried using ref (pointer to struct) but it only made things 
slower by 0.5 s.
I an not passing the result matrix to "toIdx" anymore, this is 
not necessary we just need the column value. This didn't change 
anything though.
Here is how the code looks now.

*************************************************************************
pragma(inline) static int toIdx(int matrixCols, in int i, in int 
j)
{
     return matrixCols * i + j;
}

Matrix!T matrixDotProduct(T)(Matrix!T m1, Matrix!T m2, ref 
Matrix!T initM)
in
{
     assert(m1.rows == m2.cols);
}
do
{
     /// This implementation requires opIndex in Matrix struct.
     for (int i; i < m1.rows; ++i)
     {
         for (int j; j < m2.cols; ++j)
         {
             for (int k; k < m2.rows; ++k)
             {
                 initM.data[toIdx(initM.cols, i, j)] += m1[i, k] * 
m2[k, j];
             }
         }
     }
     return initM;
}

void main() {
     Matrix!double initMatrix = Matrix!double(m1.rows, m2.cols);
     auto e = matrixDotProduct!double(m5, m6, initMatrix).to2D;
}
*************************************************************************

I tried disabling GC via GC.disable; GC.enable; before and after 
3 loops in matrixDotProduct to see what happens. But nothing 
changed :(


More information about the Digitalmars-d-learn mailing list