gpt4 book ai didi

c++ - 仅当有足够内存可用时 vector push_back

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:02:23 25 4
gpt4 key购买 nike

我目前正在构建一个使用 vector 类动态处理大量内存的代码。

代码正在使用 push_back 构建 vector ,其中重要的是要注意 vector 是二维的,表示数据矩阵。根据情况,该矩阵可能很小,也可能变得异常大。

例如,数据矩阵可以有几行,每行1000列,也可以有1000行,列数相同,全是double数据类型。显然,这很容易成为一个问题,因为 1000x1000x8 = 8 000 000 字节,因此在内存中代表 8 MB。但是多 10 倍的列和多 10 倍的行呢? (这很容易在我的代码中发生)。

我通过将数据矩阵写入硬盘来解决这个问题,但是这种方法相当慢,因为我没有充分利用 RAM。

我的问题:如何构建由 vector< vector<double> > 表示的矩阵使用 push_back , 但前提是有足够的内存可以分配。

如果内存量不够,我会继续将数据导出到 HDD 到文件中,释放分配的内存并重新开始循环。我不知道的是如何检查每个 push_back 的内存是否可用。执行。

编辑:我应该注意到我正在使用运行 Ubuntu 的 64 位机器。我不太确定操作系统分页如何以及是否正在运行,但我实际上正在做的是在存在电场和磁场的情况下对粒子进行数值计算。可能有 1 亿个粒子在超过 1000 个时间步长内移动,这是大量 GB 的数据。然而,有时我只运行几十万个粒子进行测试,这些粒子可以毫无问题地装入 RAM,从而加快了计算过程。我正在尝试创建某种通用的解决方案,该解决方案将检查是否有足够的 RAM 用于另一次计算,如果没有,则将它们移动到一个文件中。这些粒子可以添加到系统中或从中流出,所以基本上我不知道矩阵在任何给定时间会有多大。这就是为什么我需要“好吧,够了,将这些数据移出此处,以便我们可以重新开始”的方法。

最佳答案

几乎所有“我将在我的代码中将数据推送到磁盘”的替代方案都比这更好。

这是因为操作系统本身(如果我们谈论的是合理的现代操作系统,例如 Windows NT 系列和大多数 Unix 变体,包括 Linux 和 MacOS X)具有处理虚拟内存和交换到磁盘的能力,并且它将以比您可能想出的更聪明的方式来做到这一点。

此外(根据 Tony D 的评论),使用“内存映射文件”是比手动读取/写入文件更好的方法 - 这不会立即与 std::vector 一起使用或其他标准集合,但可能比在您的应用程序中手动处理读/写文件更好的选择 - 您只需说“这是一个文件,请给我一个指向代表该文件的一 block 内存的指针”,然后您使用该指针就好像文件已加载到内存中一样。操作系统将负责管理文件的哪些部分在任何给定时间实际物理存在于内存中,类似于如果您分配的内存多于系统中存在的内存,则换入和换出。

但是,这当然有限制(适用于“为您的应用程序分配超过可用 RAM 和内存映射文件解决方案”)。如果您使用的是 32 位机器(或 32 位操作系统或 32 位应用程序),您的进程可用的最大内存量将介于 2GB 和 4GB 之间 - 具体限制取决于操作系统(64 位操作系统和 32 位应用程序可能会给您近 4GB, 32 位 Windows 的常规设置总共提供大约 2GB。因此,如果您的数组足够大,地址中根本不会有“足够的位”来跟踪它。此时您需要将工作拆分为某种方式。或者转到 64 位操作系统和应用程序(这里自然需要 64 位处理器),在这种情况下,内存大小限制为 128 或 256TB(如果我的心算有效 - 65536 * 4GB)总计 - 这可能比几乎每个人拥有的磁盘空间都多,更不用说 RAM。

编辑:

根据您提供的数据做一些数学计算:每个粒子都有 X、Y、Z 位置、速度和“其他两个属性”将在 double< 中占用 6 * 8 = 48 个字节,以及 6 * 4 = 24 个字节作为 float

乘以 100M,我们得到一组数据 4.8GB。乘以 1000 个时间步,产生 4.8TB 的数据。这是一个巨大的数量,即使你有非常大的内存。使用内存映射文件并不能真正将所有这些数据一次保存在内存中。如果你的机器有相当大的内存(16GB 左右),一次在内存中保存两套可能会奏效。但是您仍然会产生大量需要在某个时候存储的数据,这很可能会花费大部分时间。对于相当现代的(单个)硬盘,50-100MB/s 左右的速度是一个合理的期望值。它可以通过某些 RAID 配置进行改进,但即使是它们,它也是每秒数百兆字节,而不是每秒千兆字节。因此,以 100MB/s 的速度存储 1TB (1000GB) 需要 10000 秒,或大约三个小时。 4.8TB 需要 15 小时。那只是存储数据,没有计算 [尽管这可能是最小的部分]。即使我们将数据集除以 10,我们也有一个多小时,除以 50,我们在分钟范围内。

无论您使用什么方法,存储和检索如此大的数据集至少可以说是非常耗时的。内存映射文件在很多方面都是“最不坏的”,因为它在这个过程中复制的数据少了一点。但是“磁盘速度”仍然是您计算速度的主导因素。

关于c++ - 仅当有足够内存可用时 vector push_back,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24547294/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com