【问题标题】:I'm using std::bitset and trying to create two arrays std::bitset with size 100,000,000,000我正在使用 std::bitset 并尝试创建两个大小为 100,000,000,000 的数组 std::bitset
【发布时间】:2020-01-13 14:51:22
【问题描述】:

我正在使用 std::bitset 并尝试创建两个大小为 100,000,000,000 的数组 std::bitset。 结果,程序仅填充了我的 RAM 的 298 MB,但必须填充〜 24 GB。我有 32 GB RAM,现在 26 GB 是免费的。当我为 x86 构建代码时,它可以编译并且可以启动,但对于 x64,它会显示以下内容:错误 C2148:数组的总大小不得超过 0x7fffffff 字节。 如何修复它并且不减小 bitset 数组的大小?

我尝试制作 2 个全局数组。 另外,我已经在 Microsoft Visual Studio -> 项目 -> name_project 属性 -> 配置属性 -> 链接器 -> 系统 -> 堆栈保留大小设置为 25,000,000(我认为必须有 KB,所以我认为我已设置为 ~ 25 GB)。

... // other libraries
#include <bitset>

std::bitset <100000000000>mas;
std::bitset <100000000000>a1;

int main() {.../* work with the arrays */...}

我想用巨大的 std::bitset 数组运行代码。

UPD:对于 x86 可以,但是对于 x64 呢?我的代码检查了整个数组,并在某一时刻停止了。

【问题讨论】:

  • 关于 32 位构建。 32 位寻址仅允许 2 GiB RAM。考虑到您的数据大小,这不是首发。如果它正在运行,那么一些非常奇怪的事情正在发生。
  • 你确定是这个尺寸吗?与sizeof 核对较小的分配。
  • masa1 不在堆栈上,因此堆栈大小不是问题。我不知道如果您保留 25 GB 堆栈会发生什么,但这听起来是个糟糕的主意。
  • 100000000000 不适合 32 位无符号整数。所以 32 位构建可能会溢出,给你一个更小的1215752192
  • 好的,但是 x64 呢?

标签: c++ windows std-bitset


【解决方案1】:

std::bitset 必须至少(并且大多数实现使用最小值)每八位使用一个字节来存储。对于 1000 亿位,这意味着每个位集需要约 12.5 GB 的内存。问题是,在 32 位系统上,整个程序的最大虚拟内存大小最多为 4 GB。其中一些被进程的内核内存保留占用了,所以很可能你只有 2 GB 的虚拟地址空间可以使用;您正在尝试使用六倍。

您的程序无法在不缩小bitset 的情况下在 32 位系统上运行。如果它声称可以运行,则可能是另一个错误;它将截断100_000_000_000 以适应32 位size_t,而是创建一个std::bitset&lt;1215752192&gt;,这只需要~150 MB 的内存,不会造成任何问题。这可以解释您观察到的 298 MB 内存使用情况;内存使用显示使用“mebibytes”(base-2,而不是 base-10,因此 KiB == 1024 和 MiB == 1048576),这使得每个数组消耗不到 145 MiB,其中两个总共消耗 290 MiB,剩下 8 MiB 用于您程序的其余部分(这似乎是合理的)。

如果它实际上在 x64 上因该错误而死,那么你就被卡住了;无论谁实现了您的 std::bitset(或任何支持它的数据结构,例如 std::array),即使在 64 位系统上也将其限制为 0x7fffffff 字节,这会将您限制为大约 170 亿位或更少的 std::bitsets。您唯一的选择是为您的标准库找到不同的提供者,或者自己重新实现。

更新: 显然您使用的是 Windows,静态数据大小限制为 2GB(0x7fffffff 字节),even on 64 bit Windows; Windows 可移植可执行文件格式(由 .exe.dll 文件使用)对每个部分使用 32 位偏移和长度,即使对于 64 位可执行文件也是如此。通过使用全局std::bitsets,您试图在图像中存储 25 GB 的静态数据,但这是行不通的。将它们移动到堆栈(在 main 的主体内声明它们不是static可能如果你像以前一样增加堆栈保留大小,但依赖它仍然是一个坏主意这么大的一堆。我建议简单地动态分配bitset(例如auto mas = std::make_unique&lt;std::bitset&lt;100000000000&gt;&gt;()),或者使用更小的bitset找到更好的方法。

【讨论】:

  • @kiileatb 我想我们需要minimal reproducible example ir 订单才能说更多。我将不得不通过,因为我只有 16 GB 可用。把我的 Cray 留在了我的另一条裤子里。
  • @kiileatb:您的错误消息告诉您那里的问题;看起来您的标准库实现者对std::bitset 或其使用的存储实现设置了严格的0x7fffffff 字节限制,所以你被卡住了;你需要不同的实现,要么来自不同的编译器编写者,要么自己重新实现。
  • @ShadowRanger 我可以更改我平台的最大尺寸还是我必须创建一个不同的实现?
  • @kiileatb VC++ 对数组的大小有一个硬编译器限制。这不是标准库产生的错误,而是实际的编译器在抱怨。我相信这是由于 Windows 对进程加载方式的技术限制。我怀疑你会在不完全改变平台的情况下解决这个问题。
  • @kiileatb 显然,static data is capped at 2GB for an image。即使将您的bitsets 拆分成更小的@s 也无济于事。您可以尝试动态分配它们(最多 8TB)。
猜你喜欢
  • 2019-10-24
  • 2014-10-13
  • 2015-11-01
  • 2020-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-22
相关资源
最近更新 更多