【问题标题】:Exchange pinned array's pointer with an unmanaged memory pointer用非托管内存指针交换固定数组的指针
【发布时间】: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> 中(它统一了指针和数组,但需要很多新的编译器技巧)
  • 好消息是,如果您将 arrayint[] 更改为 int*,那么 array[3] = 5; 仍然可以正常工作 - 除了边界检查不同(内存违规异常等)
  • @MarcGravell 但作为数组对象传入的数组数量未知。为此,我需要 n 阶不安全的闭包

标签: c# unmanaged-memory


【解决方案1】:

你不需要。 GCHandle 与托管内存有关;非托管内存不需要任何类型的GCHandle。也不能像管理数组一样与该内存通信。相反,您需要接受非托管数据是一个指针并且只是一个指针。您可以在上面抽象以隐藏这些细节,但这不会改变现实。幸运的是,对于不经意间的观察者来说,与 SomeType[] 交谈与与 SomeType* 交谈非常相似——只要您绕过自己的长度即可。

未来,即将推出的Span<T> 在统一指针和数组方面做得很好,但这目前只是实验性的。

【讨论】:

  • 你的意思是我应该等待 .Net 10 在不牺牲可读性的情况下获得更高的性能吗?但即使它是托管内存,固定也会阻止它移动,所以如果我能得到它的内部变量,我可以改变它,但是怎么做呢?也许我固定 gchandle 本身并将其内容视为内存地址?
  • 我在无限循环中声明、固定和释放了一个数组,直到它的 gchandle 的 addrOfPinnedObject 变为 4096 的倍数,但大小仅为 1000 或类似。不能使用更大的尺寸,例如 16M。也找不到将一个数组“映射”到另一个数组的区域,以便可以从第二个数组看到更改的第一个数组。
  • @huseyintugrulbuyukisik 数组从不重叠。指针可以。您似乎认为数组包含长度和指针,但事实并非如此。在托管数组中,数组内容直接在对象本身内部;因此,数组和字符串的长度不同。这就是数组永远不会重叠的原因:因为它们是不同的对象。这也是为什么不能将指针用作数组的原因。性能和编码风格通常是相互竞争的要求。但是,Span<T> 今天在 corefxlabs myget 提要中可用(但:实验性/早期)
猜你喜欢
  • 2013-01-05
  • 1970-01-01
  • 2010-09-07
  • 2011-07-03
  • 2020-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-09
相关资源
最近更新 更多