![]() |
1
7
免责声明:这个结果比预期的要长 为什么CLR不支持大型阵列CLR不支持托管堆上的大型阵列有多种原因。 其中有些是技术性的,有些可能是“范例性的”。 这 blog post 探讨存在限制的一些原因。实际上,由于内存碎片,决定限制(大写O)对象的最大大小。实现处理较大对象的成本与这样一个事实进行了权衡,即不存在许多需要如此大对象的用例,而那些需要如此大对象的用例在大多数情况下都是由于程序员的设计谬误。 从那时起,对于CLR, 每件事 是对象,此限制也适用于数组。为了加强这一限制,数组索引器使用有符号整数设计。 但是,一旦您确定了程序设计要求您拥有如此大的阵列,您将需要一种变通方法。 上面提到的博文还表明,您可以实现大型阵列,而不必进入非托管领域。 但正如Evk在评论中指出的那样,您希望通过PInvoke将数组作为一个整体传递给外部函数。这意味着您将需要非托管堆上的数组,否则必须在调用期间对其进行封送处理。对这么大的数组进行封送处理是个坏主意。 解决方法因此,由于托管堆是不可能的,因此您需要在非托管堆上分配空间,并将该空间用于阵列。 假设您需要8 GB的空间:
太棒了现在,虚拟内存中有了一个区域,您可以在其中存储多达8 GB的数据。 如何将其转换为数组? 在C语言中有两种方法# “不安全”方法这将允许您使用指针。指针可以转换为数组。(在香草C中,它们通常是同一个) 如果您对如何通过指针实现2D数组有很好的想法,那么这将是您的最佳选择。 这是一个 pointer “马歇尔”方法您不需要不安全的上下文,而是必须将数据从托管堆“封送”到非托管堆。您仍然需要理解指针算法。 您要使用的两个主要功能是 PtrToStructure 反之亦然 StructureToPtr . 使用它,您将从非托管堆的指定位置获得一个值类型(例如double)的副本。对于另一个,您将在非托管堆上放置一个值类型的副本。 这两种方法在某种意义上都是“不安全的”。你需要知道你的 pointers 常见缺陷包括但不限于:
您可能希望将二维阵列设计转换为一维阵列设计 在任何情况下,您都希望将其打包到一个具有适当检查和deststructor的类中。 灵感的基本示例下面是一个基于非托管堆的“类似”数组的泛型类。 功能包括:
如果你注意到了,我没有做任何类型检查,所以如果
您必须自己实现的功能包括:
所以,如果可以的话,请将此作为一种灵感。
|
![]() |
2
1
我使用了下面的“封送”方法的基本示例
answer
从…起
MrPaulch
要创建以下类,请调用
现在我可以用巨大的矩阵调用Intel MKL库,例如:
对于参数
|
![]() |
Javid · 远程计算机关闭后,套接字仍保持连接 9 年前 |
![]() |
deadpool_Y7 · 检查大写字母是否在字符串中 9 年前 |
![]() |
mamcx · 如何在OSX和F#中使用Roslyn脚本? 9 年前 |
![]() |
William Hodges · 如何编写c#日志文件?[已关闭] 9 年前 |