【发布时间】:2016-09-14 14:40:35
【问题描述】:
我正在固定和取消固定:
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# 为所有使用“数组”对象的所有内容使用对齐的分配空间,直到我取消固定它。
【问题讨论】:
-
为什么要换东西?如果您有一个非托管指针,则首先不需要 gchandle;只是...传递指针,作为
byte*(或其他)或IntPtr。 -
我在计算方法中多次使用数组对象。它的内部非常简单,我不想让它变得更复杂。当我做 array[3]=5 时,它将使用来自 alingnedAlloc 的非托管空间
-
是的,但是一旦你分配了非托管内存,你就没有数组了。如果您有使用数组的代码,您只需更改该代码;现在是错误的。你需要在整个过程中谈论指针。或者,希望很快,在
Span<T>中(它统一了指针和数组,但需要很多新的编译器技巧) -
好消息是,如果您将
array从int[]更改为int*,那么array[3] = 5;仍然可以正常工作 - 除了边界检查不同(内存违规异常等) -
@MarcGravell 但作为数组对象传入的数组数量未知。为此,我需要 n 阶不安全的闭包
标签: c# unmanaged-memory