【发布时间】:2013-09-07 19:07:25
【问题描述】:
我正在尝试编译一个 5.7 MB 大的 C++ 文件。我正在 64 位 Linux 系统上构建一个 64 位 Linux 可执行文件。不幸的是,g++ 4.7.2 不合作:
g++: internal compiler error: Killed (program cc1plus)
使用top 观察表明该进程在此之前达到了大约 2.2 gigs 的内存。我尝试设置--param gcc-min-expand=0 并且还玩了--param gcc-min-heapsize,但这并没有解决问题。使用 -O0 禁用优化也没有帮助。
我也试过用clang编译,但结果差不多。它在超过 2 gigs 的内存后也出现了段错误。我没有尝试使用 clang 的任何额外选项,因为我对它不太熟悉。
有问题的源文件包含几个地图的 C++11 风格初始化。
typedef std::map<std::string, int> StringToIntMap;
StringToIntMap someData = {{"SOMESTRING", 1}, ..};
我想要的是最好用gcc编译文件,虽然如果clang可以代替,我也可以忍受它。从了解内部情况的人那里了解幕后发生的事情也很有帮助。如果我有一个包含 300 000 个元素的映射,其中字符串的长度约为 5 个字节,并且每个元素对应一个 int,那么这就是几兆字节的数据,我无法轻易想象初始化程序如何将其炸毁到需要千兆字节才能编译。
为了抢占我不应该有这么大的源文件的 cmets。我知道我可以在运行时从数据文件中读取数据,这就是程序现在所做的,但我的用例是程序的执行时间是最重要的因素。
【问题讨论】:
-
哈哈。我确信标准的附录 B 允许编译器比这更早开始失败:/
-
将其移入源代码实际上并不会带来太多好处。现在,加载可执行文件需要 M 时间 + N 时间来初始化地图。预加载数据后,您最终会得到一个需要(大约)M+N 时间来加载的可执行文件。给定需求分页,这将发生在 M 时间开始执行和 N 时间在运行时分页数据。终极区别:更多的工作,但执行速度几乎没有差异。
-
@JerryCoffin 现在如果这是
boost::flatmap,它可能会好很多,但即便如此,constexpr初始化可能会更好。 -
如果你创建一个对向量,然后动态生成地图会发生什么?
-
@Mehrdad 你浪费内存 :) 你可以只使用带有
lower_bound、upper_bound和equal_range的向量 :/ (或者实际上,提升平面地图,它使用更友好的界面来做到这一点)