Обмен указателя закрепленного массива с указателем неуправляемой памяти
Я прикалываю и открепляю с помощью:
GCHandle pinArray(object a)
{
return GCHandle.Alloc(a, GCHandleType.Pinned);
}
void unpinArray(GCHandle h)
{
h.Free();
}
до и после метода opencl, поэтому массив не перемещается во время вычислений на нем. Теперь мне нужно обменять указатель резервного массива с выровненным указателем неуправляемого массива, чтобы иметь более быстрые операции чтения / записи.
Но я не смог найти ничего, как "изменить значение указателя массива gchandle".
Мне нужно что-то вроде "обменного" метода:
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);
нужно ли это отражение для доступа и изменения этой переменной? Есть также много методов C#, использующих эти массивы внутри метода вычисления, так что это даст большую скорость даже на C# пространстве? Поэтому я стараюсь позволить C# использовать пространство alignAlloc для всего, что использует объект "массив", пока я не откручиваю его.
1 ответ
Вам не нужно. GCHandle
относится к управляемой памяти; неуправляемая память не требует какого-либо GCHandle
, Также невозможно говорить с этой памятью, как будто это управляемый массив. Вместо этого вы должны принять, что неуправляемые данные являются указателем и только указателем. Вы можете абстрагироваться от всего этого, чтобы скрыть эти детали, но это не меняет реальности. К счастью, случайный наблюдатель, разговаривая с SomeType[]
очень похоже на разговор с SomeType*
- до тех пор, пока вы проходите длины вокруг себя.
В будущем наступающем Span<T>
делает большую работу по объединению указателей и массивов, но это пока только эксперимент.