- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我目前正在构建一个使用 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/
我有这个析构函数,它在运行时产生错误“vector 迭代器不可取消引用”。 gridMatrix 是一个 std::vector * > * > * > * > 我添加了 typename 和 typ
我有一个 vector 的 vector ,比方说 std::vector > my2dArray; 现在我想要一个 vector ,其中包含 my2dArray 中 vector 的大小。手动这看起
假设我有一些 vector :v1、v2、v3 假设我还有一个 vector 来保存这些 vList = {v1, v2, v3} 如果我同步了 (vList),这是否意味着 v1、v2 和 v3 也
我正在创建一个 char 的二维 vector 数组作为类变量,但我在将 vector 添加到 vector 数组中时遇到了麻烦。 我正在使用 C++ 11 标准运行 gcc。 我尝试使用 vecto
如何修改 Vec基于 Vec 中某项的信息没有对向量的不可变和可变引用? 我已尝试创建一个最小示例来演示我的特定问题。在我的真实代码中,Builder struct 已经是其他答案提出的中间结构。具体
这个问题在这里已经有了答案: What is the idiomatic Rust way to copy/clone a vector in a parameterized function? (
在我的程序中,我有一个整数 vector 的 vector 。现在我想从 vector 的 vector 中取出一个 vector 并在另一个 vector 容器中对其进行操作,但是我得到了错误...
我得到一个vector>数据由 OpenCV 提供。由于某些原因(例如偏移/缩放),我需要转换数据 Point至Point2f 。我怎样才能做到这一点? 例如: std::vector > conto
我有一个函数,该函数应使用来自字符串类型的给定 vector vector 中的某些元素初始化来自字符串类型的空 vector vector 。我的语法看起来像这样 std::vector> extr
我得到一个vector>数据由 OpenCV 提供。由于某些原因(例如偏移/缩放),我需要转换数据 Point至Point2f 。我怎样才能做到这一点? 例如: std::vector > conto
这里有很多类似的问题,但我没有真正找到任何可以特别回答我的问题的问题。 我有一个 vector 的 vector 作为类的属性。另一个属性是 bucket_count。我想将 vector 的 vec
如果我像这样创建一个 vector 的 vector : std::vector> myVectorOfVectors; 然后用一些东西填充它: std::vector myVector1; myVe
我正在用 C++ 编写自定义 vector 类。我对这样的代码有疑问: vector vec; vec.push_back(one); vec.push_back(two);
这是我发布的问题 c++ program for reading an unknown size csv file (filled only with floats) with constant (b
vector> a; for (int i=0;i v(i+1); iota(v.begin(),v.end(),1); a.push_back(v); } a.erase(a.beg
也许已经晚了,但我不明白为什么我会得到一个超出此代码范围的 vector 下标: int m = 3; int n = 2; std::vector> path(m, std::vector(n, 0
这个问题真的很奇怪,我似乎找不到任何导致它的原因。 所以这里有一个赋值运算符重载函数,鸟类和哺乳动物都是 vector 。 (下面是类) const Register& Register::opera
我怎么去 std::vector> 只是 std::vector> ?有真正有效的方法吗? 最佳答案 我会做这样的事情: #include #include int main() { //
我正在尝试将这些 vector 中的一些数据写入文本文件。当我运行代码时,它返回运行时错误。 Category、Product、Cart、Customer和Address都是struct 包含每个 g
显然它会因您使用的编译器而异,但我很好奇执行 vector> 时的性能问题与 vector*> ,尤其是在 C++ 中。具体来说: 假设您的外部 vector 已满,您想要开始将元素插入到第一个内部
我是一名优秀的程序员,十分优秀!