.NET Memory Usage
For all developers that
use MKL under .NET
As every
.NET developer knows memory usage is managed from Garbage Collector. This layer determines
when memory is released and how to reorganize it. It allocates spaces for each
thread separately and avoid conflicts.
For this, we
programmers often don’t know exactly what really happen at this level, the
details.
In general,
this is enough, because GC has been built in order to permit developer to
concentrate at higher levels.
IntPtr x = new IntPtr(0);
double[] x_init = null;
x = mkl_malloc(sizeof(double) * n, 64);
Marshal.Copy(x_init, 0, x, n);
//use x pointer …
mkl_free(ref x);
This set of
instructions define a memory space for an array of double and assign a memory
pointer to x. This pointer x is then passed to a function like this:
[DllImport("mkl_rt.dll", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true,
SetLastError = false)]
internal static extern int dtrnlspbc_init(
ref IntPtr handle,
ref int n,
ref int m,
IntPtr x,
IntPtr LW,
IntPtr UP,
double[] eps,
ref int iter1,
ref int iter2,
ref double rs
);
Everything
seems to work, but this is a very subtle felling!
Yes,
because memory is in the heap area managed by GC and can be moved, reorganized.
This means that your pointer x is not reliable.
We spend a
lot of time to fight against strange results, sometimes good, sometimes not.
Where was the trick? Was Intel fault of our fault? I don’t like this word “fault”,
but the question was where the issue?
At the end,
we got the solution!
This was: Pin
the pointer with the correct syntax and methods.
GCHandle x_handle = GCHandle.Alloc(x_init, GCHandleType.Pinned);
x = x_handle.AddrOfPinnedObject();
//use x pointer …
x_handle.Free();
Now GC can’t
move the pointer and the array used by API function is always located.
I hope these
notes useful for poor developer always alone in the ocean of troubles.
Part 1 | Part 2 | Part 3 | Part 4