I'm pinning and unpinning with:
GCHandle pinArray(object a)
{
return GCHandle.Alloc(a, GCHandleType.Pinned);
}
void unpinArray(GCHandle h)
{
h.Free();
}
before and after an opencl method so array does not move while computing on it. Now I need to exchange backing array pointer with an aligned unmanaged array pointer to have faster read/write operations on it.
But I couldn't find anything like "change value of gchandle backing array pointer" info.
I need something like an "exchange" method:
GCHandle h=pinArray(array);
// how to?
IntPtr oldBackingArray=exchange(h,alignedMallocCSpace(10000000,4096));
// unmanaged operations
copyValues(h,oldBackingArray);
compute(array,...); // only passing with "array" for simplicity everywhere
array[3]=5;
l=array.toList();
compute(array,....);
Console.WriteLine(array[3]);
copyValues(oldBackingArray,h);
freeCSpace(exchange(h,oldBackingArray));
unpinArray(h);
does this need reflection to access and change that variable? There are also many C# methods using those arrays inside compute method so will it give more speed even on C# space too? So I'm tring to let C# to use alignedAlloc space for everything using "array" object until I unpin it.
You don't need to. The GCHandle
relates to managed memory; unmanaged memory does not require any kind of GCHandle
. Nor is it possible to talk to that memory as though it is a managed array. Instead, you need to accept that the unmanaged data is a pointer and only a pointer. You can abstract over the top of that to hide these details, but it doesn't change the reality. Fortunately, to the casual observer, talking to a SomeType[]
is very similar to talking to a SomeType*
- as long as you pass the lengths around yourself.
In the future, the upcoming Span<T>
does a great job of unifying pointers and arrays, but that is only experimental at the moment.