【问题标题】:how can I initialize 2D array of huge size 1000000x1000000? [closed]如何初始化 1000000x1000000 的大尺寸二维数组? [关闭]
【发布时间】:2013-09-09 22:39:15
【问题描述】:

我正在使用 g++ 编译器在 ubuntu 中开发一个 cpp 项目,我需要创建一个大小为 1000000x1000000 = 10^12 个元素的矩阵,其条目是布尔变量。但是我的 g++ 编译器只允许我为大约 1000x1000 个元素分配空间。如何克服为这个巨大的矩阵分配空间的问题?

【问题讨论】:

  • 您不需要这么大的矩阵。让我们假设它需要一秒钟来处理每个条目(并且你有足够的内存!)那么它将需要 31000 年!所以我怀疑这是一个结局
  • 也许你可以退后一步,解释一下你是如何得出你需要这个大小的数组的结论的。
  • 好的。假设矩阵的大小是 mxn。我们需要为每个唯一的关键字文件(mxn)对存储一个布尔值,其中关键字的最大数量(m)约为 10^6,并且我们数据库中的最大文件数量(n)假设为 10^6。跨度>
  • 如果这是一个家庭作业,它的目的可能是让你想到替代技术(稀疏数组、树、哈希表……)

标签: c++ linux gcc memory-management multidimensional-array


【解决方案1】:

你不能,除非你有至少 125GB 的 RAM(假设你每个 bool 只需要一位)。如果您真的需要这么大的结构,则需要购买大量 RAM 或考虑磁盘算法。

但很有可能解决您的问题实际上并不需要 10^6 x 10^6 数组,因此您应该首先重新考虑您的算法。

有些库允许磁盘上的数据结构(我想到了http://roomy.sourceforge.net/,还有一个我暂时记不起名字的库),但是磁盘访问比 RAM 慢几个数量级。除非您对此进行了彻底的考虑,否则您可能不会对基于磁盘的解决方案的性能感到满意。

【讨论】:

  • 还有其他替代方法可以实现这一目标吗?使用外部存储,例如使用文件概念还是使用数据库?
  • 我知道这是一个奇怪的问题,但如果有任何替代方法,例如在编译或重置我从其他帖子中读取的堆栈大小时设置标志,请试试我的运气。该算法是这样设计的(数据挖掘项目),这个矩阵实际上需要在服务器中存储 10^6x10^6 个条目的布尔值,但想在我的本地机器上测试它的限制。无论如何感谢您的信息和图书馆参考。
  • 1) 在编译时或运行时初始化没有区别。无论哪种情况,它都需要内存。 2)您不需要“测试极限”。一支铅笔和一张纸就足以计算出需要多少内存。 :-)
【解决方案2】:

假设:

  • 您使用的是 64 位系统,因为 32 位系统没有足够的虚拟地址空间来容纳如此大的数组
  • 您有足够的物理内存和磁盘交换空间来容纳阵列

然后您将需要使用动态分配的数组。一般来说,链接器/加载器在静态分配变量方面对它可以处理的内容有固定的限制。

试试:

static_assert(sizeof(size_t) == 8, "64-bit required");

constexpr size_t N = 1000000;

vector<bool> V(N*N);

inline decltype(V[0]) get(size_t x, size_t y) { return V[x*N + y]; }

除非您有大约 100GB 的物理内存 - 请记住,随机位访问会导致整个页面被交换到磁盘,这需要毫秒级。

【讨论】:

  • 是的,我使用的是 64 位系统,但只有 3.6GB RAM。你能告诉我磁盘交换空间是什么意思吗?
  • “动态分配的数组”,你的意思是当我们初始化元素时?在这种情况下,我将不得不将矩阵中的所有条目初始化为零。 vector 在这种情况下有效吗?访问这些位不是一个大问题,因为它不是算法中的频繁操作,但存储它们很关键,甚至毫秒级的时间也是可以接受的。
  • @annunarcist:您缺少一些操作系统的基本知识。阅读Virtual MemoryDynamic Memory Allocation
  • 据我了解,您试图说物理内存/内存是指主存储(我的系统上的物理 RAM-3.6GB),而用于磁盘交换的空间是从辅助存储(磁盘)使用的,这意味着通过从辅助存储(磁盘)分配空间,可视化允许进程拥有比实际物理内存更多的内存。如果我错了,请纠正我。
  • 从我做的文献作业来看,是不是vector的每个元素只用了一位内存来存储?
【解决方案3】:

如果大多数值为零(假),请尝试考虑稀疏矩阵。这将节省空间。通常你不能创建这么大的数组。


这里vector&lt;bool&gt;::max_size() 将是正确的限制。但实际上标准并不能保证这种分配是可能的。

注意:我的 msvc 编译器显示总数组大小不应超过 0x7fffffff

【讨论】:

  • 在 32 位构建中,限制确实是 0x7fffffff。我不确定 64 位是否有相同的限制
  • 我在 (vs2012) 中设置 x64 目标时编译了相同的内容。它也显示相同的上限。 @MooingDuck
  • 我检查了,当 MSVC2012 设置为 x64 时,vector.at( 采用 unsigned __int64。但你是对的,即使以 x64 为目标,我也不能分配超过 0x7FFFFFF 的空间。显然这是 32 位版本的 MSVC2012 中的一个错误:connect.microsoft.com/VisualStudio/feedback/details/553756/…。一个有趣的解决方法是使用std::vector
  • 该问题被标记为linuxgcc,因此MSVC 可能施加或不施加的任何限制都无关紧要。
  • 相关便携图为std::vector&lt;T&gt;::max_size()
猜你喜欢
  • 2011-12-08
  • 2020-07-25
  • 2012-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多