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 :(