【问题标题】:Create too large array in C++, how to solve?在 C++ 中创建太大的数组,如何解决?
【发布时间】:2018-03-17 14:55:10
【问题描述】:

最近,我使用 C++ 工作,我必须创建一个 array[60.000][60.000]。但是,我无法创建这个数组,因为它太大了。我试过float **array 甚至static float array 但没有什么是好的。有人有想法吗? 感谢您的帮助!

【问题讨论】:

  • 如果您真的需要这么大的数组,我建议您考虑使用内存映射文件。如果您无法将整个内容放入内存中,您的操作系统只会映射到您访问的页面。
  • 另外,您在 64 位操作系统上,对吧?
  • 是的,我使用的是 Windows 64 位
  • 你想一次性处理内存中的所有数据吗?拥有一切重要吗?如何将其重组为更小的块?
  • 只是出于好奇,这个庞然大物是干什么用的?想想我担心将几 MB 作为 char[] 数组传递!

标签: c++


【解决方案1】:

大小为60,000 x 60,000 的矩阵具有3,600,000,000 元素。

你使用的是float,所以它变成了:

60,000 x 60,000 * 4 bytes = 14,400,000,000 bytes ~= 13.4 GB

你的机器有那么多内存吗?


请注意,堆栈与堆的问题甚至无关紧要,除非您有足够的内存开始。


以下是可能出现的问题列表:

  • 内存不足。
  • 如果矩阵是全局声明的,则会超出二进制文件的最大大小。
  • 如果矩阵被声明为一个局部数组,那么你会炸掉你的堆栈。
  • 如果您正在为 32 位编译,则已远远超出 2GB/4GB 寻址限制。

【讨论】:

  • 它是怎么失败的?错误信息?崩溃?
  • “此应用程序已请求运行时以不寻常的方式终止它。”我使用 devC,这就是我得到的 zzz。
  • @Mysticial - 这可能是编译器/链接器对 BSS 施加的限制。
  • 你能告诉我们你是如何声明数组的吗?如果你在做float array[60000][60000],那么你会炸掉你的堆栈。 (或者如果它是全局的,你可能会超出编译器的限制。)
  • 编译为 32/64 位与操作系统是否为 32/64 位完全不同。您需要both 64 位操作系统并编译为 64 位。但根据您的其他评论,您只有 4GB 的内存。所以你将无法制作这种大小的矩阵。
【解决方案2】:

“60.000”实际上是指“60000”吗?如果是这样,则所需内存的大小为60000 * 60000 * sizeof(float),大约为 13.4 GB。典型的 32 位进程仅限于 2 GB,因此不适合的原因很明显。

另一方面,假设您的机器有足够的 RAM,我不明白为什么您不能将其放入 64 位进程中。

【讨论】:

  • 是的,我有 >20GB 硬盘和 4GB 内存
  • @Kingfisher 4GB 内存?所以你依赖交换?!?!?
  • @Kingfisher - 那是你的问题 - 你把内存 (RAM) 和硬盘空间混淆了,它们都是不同的东西。
【解决方案3】:

在运行时分配内存——考虑使用内存映射文件作为支持。就像每个人都说的那样,14 场演出是很多记忆。但是找一台14GB内存的电脑也不是不合理,必要时对内存进行分页也不是不合理。

使用这种大小的矩阵,您可能会对内存访问性能非常好奇。请记住考虑目标架构的缓存粒度,如果您的目标具有 TLB,您可能能够使用更大的页面来减轻一些 TLB 压力。再说一次,如果您没有足够的内存,您可能只关心存储 I/O 的速度。

如果还不是很明显,您将需要一个支持 64 位地址空间的架构,以便直接/方便地访问此内存。

【讨论】:

  • 内存映射文件“咬”进进程的虚拟内存地址空间。因此,即使使用内存映射文件,32 位进程一次也无法访问超过 2 GB(或“感知大地址空间”时为 4 GB)。 64 位进程可以,但它也可以直接寻址那么多内存,这违背了使用内存映射文件的目的。 OTOH,如果目标是根据需要选择性地加载实际物理文件的片段,而不是在任何给定时间映射太多文件,那么内存映射文件是合适的。
【解决方案4】:

要初始化你想要的二维浮点数组,你需要:

60000 * 60000 * 4 字节 = 14400000000 字节

这大约是 14GB 的内存。那是很多记忆。理论上来说,你需要运行一台 64 位的机器,更不用说安装了相当多 RAM 的机器。

此外,在大多数情况下几乎不需要分配这么多内存,您确定这里不能进行优化吗?

编辑:

根据您的 cmets 关于其他答案的新信息:您只有 4GB 内存 (RAM)。因此,您的操作系统将不得不在硬盘驱动器上至少分页 9GB,实际上可能更多。但是您也只有 20GB 的硬盘空间。这几乎不足以对所有数据进行分页,尤其是在磁盘碎片化的情况下。最后,(我可能错了,因为您没有明确说明)您很可能正在运行 32 位机器。这实际上无法一次处理超过 4GB 的内存。

【讨论】:

    【解决方案5】:

    我也有这个问题。我做了一个解决方法,我将数组分成多个部分(我允许的最大数组是 float A_sub_matrix_20[62944560])。当我在 main() 中仅声明其中一个时,它似乎被放入 RAM 中,因为我在 main() 启动后立即遇到运行时异常。我能够将该大小的 20 缓冲区声明为有效的全局变量(看起来像以全局形式存储在 HDD 上 - 当我将 A_sub_matrix_20[n] 添加到 VisualStudio 的监视列表中时,它给出了一条消息“正在读取文件”)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-16
      • 1970-01-01
      • 2014-03-07
      • 2017-07-08
      • 2020-01-12
      • 2020-07-25
      • 2014-05-06
      • 2020-08-29
      相关资源
      最近更新 更多