我应何时使用GCC的-pipe选项?

78

GCC 4.1.2文档-pipe选项的解释如下:

-pipe

使用管道而不是临时文件来在编译过程的各个阶段之间进行通信。这种方式在某些系统上会失败,因为汇编器无法从管道读取数据;但GNU汇编器没有问题。

我认为如果我的系统汇编器不支持管道,就可以从错误消息中看出。那么除了这个问题,什么情况下使用该选项更为重要?决定是否使用该选项应考虑哪些因素?


1
我认为你可以放心,如果你的GCC使用不支持管道输入的汇编器进行配置,那么GCC将拒绝-pipe选项或忽略它(更可能是后者)。 - Jonathan Leffler
6个回答

56

通常不会有任何区别

它有+-的考虑因素。从历史上看,同时运行编译器和汇编器会占用大量RAM资源。

Gcc在今天的标准下很小,-pipe添加了一点多核可访问的并行执行。

但同样地,CPU速度非常快,它可以创建临时文件并读取它而您甚至都没有注意到。而且由于-pipe从未是默认模式,它偶尔会出现一些问题。单个开发者通常不会注意到时间差异。

现在,有一些大型项目。您可以检查一个单独的树,将构建所有Firefox、NetBSD或类似的东西,即真正庞大的东西。例如,包含X的所有内容作为一个次要子系统组件。当工作涉及数百万行代码中的数千个C文件时,您可能会注意到差异,也可能不会。如您所知,人们通常只在一段时间内处理其中的一小部分内容。但如果您是发布工程师或正在构建服务器上工作,或正在更改stdio.h中的某些内容,则可能希望构建整个系统以查看是否有任何错误。现在,每一点性能都很重要...


54
“CPU 速度非常快,以至于它可以创建临时文件并将其读回而你甚至都没有注意到。” 这个说法是错误的。瓶颈不在 CPU 上,而是在驱动器的 I/O 上。想象一下,由于某种原因你正在使用一个慢速 USB 存储设备编译一个大型项目:你会对等待所有的读/写操作感到非常烦恼。当然,GNU/Linux 使用文件缓存代替实际写入。但这并不是 GCC 的功劳。所以,“我们必须使用 -pipe 吗?” 是的,最好使用。 - Hi-Angel
7
@angel: 我怀疑这样的输入输出延迟甚至不会成为现代系统关键循环中的一部分:加上内存缓存的影响,只要您有足够的内存来存储最近使用的文件,所有实时操作都将在那里发生,在设备上进行 "真正的写入 "将在后续异步进行。 我怀疑现代系统的关键循环中甚至不会包含此类输入/输出延迟。此外,由于存在内存缓存,只要您具有足够的内存来存储最近使用的文件,所有实时操作都会在缓存中进行,而 "真正的写入" 则会稍后异步地在设备上进行。请注意,此处翻译的目标是使原文的意思更易懂,但不改变其含义。 - Cyan
6
由于操作系统拥有大量可用的RAM页面缓存,特别是在将/tmp挂载(应该这样做)到RAM上或没有完整恢复写入屏障时,此时I/O的实际开销仍然在CPU上。 - DigitalRoss
3
当使用大型C++模板(例如在OpenSCAD中使用CGAL)时,我发现防止使用管道,而是要求它在文件上使用汇编器,可以防止机器耗尽RAM并击中交换空间。这适用于相对较低的RAM机器,如512MB或1G,还取决于是否使用-g和-O2。 - don bright

51

在我们处理一个中等规模的项目时,添加-pipe并没有明显的构建时间优势。我们遇到了一些问题(如果遇到错误有时无法删除中间文件,如果我没记错的话),所以因为没有带来任何好处,我们停止使用它而不是试图解决这些问题。


25
基于证据的回答比“它不使用磁盘,所以可能更好”的回答更可靠,我给这个回答点个赞。 - Elazar Leibovich
4
请参考 @peterkarasev 的证据,表明当您使用分布式文件系统时,-pipe 确实可以产生积极的影响。 - James Moore

34

我现在正在尝试这个,当源代码/构建目标位于NFS(linux网络)时,构建速度似乎要快些。然而,内存使用率很高。如果您从未填满RAM并且将源代码放在NFS上,则使用-pipe似乎是一种胜利。


14

说实话,没有太多不使用它的理由。 -pipe 只会使用更少的 RAM,如果该系统正在构建代码,我认为RAM应该有足够的量。如果您的系统使用写入并在路上删除所有临时文件的更保守的文件系统(例如 ext3),它可以显着提高构建时间。


1
你做出了错误的假设 - 构建代码的机器通常具有非常少的内存。例如,考虑树莓派。 - James Moore
9
@JamesMoore,当你遇到受限系统时,会进行交叉编译,而不是在目标平台上处理内存问题,对吗? - nurettin

9

其中一个优点是使用-pipe选项时,编译器与文件系统的交互会更少。即使是在RAM磁盘上使用临时文件,数据仍然需要通过块I/O和文件系统层进行处理,而使用管道则更加直接。

使用文件时,编译器需要先完成写入操作,才能调用汇编器。使用管道的另一个优点是,编译器和汇编器可以同时运行,并更好地利用SMP架构。特别是当编译器需要等待源文件数据(因为阻塞I/O调用)时,操作系统可以将完整的CPU时间分配给汇编器,让其更快地完成工作。


0

从硬件角度来看,我想你可以使用-pipe来保护您的硬盘寿命。


15
我坚信Linux并没有真正地将文件保存到硬盘中,而是仅仅将它放在了RAM缓存中。 - LiraNuna

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接