Having a bit of a problem here on a matrix multiplication code.
I seem to lose precision on large matrices multiplications (my code runs fine on small matrices).
My loop is the following :
for (int j = 0; j < columns; j++)
{
float[] column = otherMatrix.Column(j);
for (int i = 0; i < rows; i++)
{
double s = 0;
for (int k = 0; k < size; k++)
s += this[i,k] * ((double) column[k]);
result[i, j] = (float)s;
}
}
As you can see, I force a (double) precision to make sure I don’t lose precision when multiplying my two floats.
Looking at IL code, I can see two conv.r8 which make me think that IL code has this float-to-double precision conversion in it.
However, when running it and having a look at the disassembly (x86 machine), I see the following :
0000024e fld dword ptr [edx+eax*4+8]
00000252 fmulp st(1),st
00000254 fadd qword ptr [ebp-64h]
00000257 fstp qword ptr [ebp-20h]
It makes me think that JIT has thought that since I’m already multiplying floats, it shouldn’t use double precision multiplication but single precision multiplication, giving me the errors I’ve been tracking.
Am I right ?
Is there any way to force this double precision multiplication ?
Thanks
I think you’re misinterpreting the assembly. I believe that FMULP always operates on the 80-bit registers. I would be surprised to see the JIT doing the wrong thing here.
I suggest you use my
DoubleConverterto write out the precise values before and after the arithmetic. That way you should get a better idea of what’s going on.