有一些人推崇 RPM 式的预编译二进制或其他这类的安装程序方法所带来的便利。但这可能并不经济,尤其是对那些经常被使用的程序而言:预编译的二进制的运行速度将永远比不上为 您的机器优化编译的那些程序的速度,但如果使用分布式编译器,您就可以两者兼得:快速的编译速度和更快的应用程序。您所需要的就是 distcc。
<!--START RESERVED FOR FUTURE USE INCLUDE FILES--><!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters --> <!--END RESERVED FOR FUTURE USE INCLUDE FILES-->
考虑到开放源代码软件的一些特性,很多 Linux™ 应用程序被分配到包含源代码的“tarball”中,在运行应该程序之前,需要编译这些源代码。相当多的应用程序的建立都需要花费几个小时的时间。在本文 中,我们讨论了如何使用分布式 C 编译器 distcc 来加速编译这些源代码,这样您就可以更快地使用它们。
一些 Linux 应用程序可以用作 RPM(Red Hat Package Manager)文件。对最终用户来说,这些通常是快速安装并运行应用程序的一个好方法。不过,用户常常还有一个选择,尤其是对开放源软件,这个选择就是 .tar.gz(即“tarball”),它通常包含最终用户需要编译的源代码。尽管相对于同族的 RPM 来说,建立 tarball 稍微需要点技巧,但它有它的一些优势:
- 该应用程序通常都安装在 /usr/local 中,这意味着您可以很轻松地在您的机器上删除这些安装程序,同时仍保留您自己的应用程序
- 您可以稍微调整代码,使其更合乎您的需要
- 有很多优化方案可用
最后一点是我个人最欣赏的。作为一个具有一定能力的用户,我希望能够将程序对我的 Athlon XP 处理器 的使用发挥到极致;我可以在编译时完成这一任务。但有一个警告:启用优化意味着要增加编译时间 —— 编译器尝试 去做一些智能的事情,例如追随循环并分析出常量。最终结果是牺牲编译时间来换取极快的代码。
让我们来看一个典型的应用程序:OpenSSH。我刚从网站上(请参见 参考资料 ) 下载了 openssh-3.7p1.tar.gz tarball,并打算将它用作“测试”应用程序。
首先,我提取了 tarball:
me@mymachine:~> tar xvzf openssh-3.7p1.tar.gz
在这里, x
提取了 tar 文件, v
给出了详细的输出, z
告诉 tar 命令去 gunzip(解压缩)文件, f
是我希望提取的 tar 文件。如果是 .tar.bz2 文件,我会用 j
来取代 z
,用它来指出 tar 应该 bunzip 文件而不是 gunzip 它。(在命令行中输入 man tar
可以得到 手册页提及的有关 tar 及其选项的更多资料)
然后切换到新创建的 openssh 目录:
me@mymachine:~> cd openssh-3.7p1
我将为 gcc 指定一些编译器选项,因为这是我建立源代码将使用到的工具,并且我希望能够利用我机器的一些特性。由于我使用的是 bash,我将使用 export
命令(在 tcsh 或其他类似 shell 中使用 setenv
命令):
me@mymachine:~/openssh-3.7p1> export CFLAGS="-O3 -march=athlon-xp \
-funroll-loops -fexpensive-optimizations"
me@mymachine:~/openssh-3.7p1> export CXXFLAGS=$CFLAGS
注意 -march
标志。由于我的工作站中有一个 AMD Athlon XP 处理器,所以我可以使用 gcc 3.x 中 的这个便捷 -march=athlon-xp
开关来自动开启处理器特定优化,比如 SSE。我还可以使用 -march=pentium4
或者 -march=pentiumpro
, 或者完全忽略它们。请查看 gcc 的手册页来获得可用优化的完整列表和描述。
这些就是要对编译器选项执行的操作。如果您对这些并不熟悉,那么您会很高兴地了解到,您可以将它放置在 ~/.bashrc 文件中,并且在默认情况下使用这些选项。
我需要做的下一件事情是,使用希望我的 SSH 编译中包含的选项来配置编译我的机器。 我可以通过键入以下代码查看这些选项:
me@mymachine:~/openssh-3.7p1> ./configure --help
我可以根据自己的需要使用这些选项中的一些或全部,不过,默认的那些选项就可以满足我的需要,所以,我只需运行 configure
选项即可:
me@mymachine:~/openssh-3.7p1> ./configure
现在我需要做的就是编译源代码,使用 make
命令就可以轻松做到这一点:
|
术语表
make 一个免费软件编译工具,它使用 makefile 来编译和链接源代码,以创建可执行的二进制文件。请参阅 man make 。
configure 为 make 生成 makefile 的脚本,是 tarball 使用者最先要用到的部分: ./configure && make && make install 。
makefile 通过 make 使用的配置文件;它定义了包含源代码的源文件的位置,以及如何编译和链接这些源代码。
automake 生成包含在另一个 makefile 中的 makefile。该工作是“幕后进行”的。请参阅 man automake 。
make clean 删除所有原有二进制对象文件和可执行文件,这样您就可以对以前编译过的程序进行一次“clean”编译。
build 预处理、编译和链接应用程序的过程。
preprocess 编译前展开“include”文件的过程(一些语言不需要这一步)。
compile 将人工可读的、文本源代码转换为机器可读的、二进制对象代码的过程。
linking 将包含二进制对象代码的单独文件链接成单个可执行文件的过程;或者在库外进行链接。
tarball 包含很多文件的一个文件,用于归档、备份和分发源文件。通常用 gzip 或 bzip 压缩,tar 文件(或 tarball)使用 tar 打包和解包。请参阅 man tar 。
|
|
me@mymachine:~/openssh-3.7p1> make
此刻我可以去喝一杯咖啡,因为该编译过程可能要花费一段时间。一旦完成该过程,我将得到我所需要的 OpenSSH 的所有部分, 而且由此产生的 OpenSSH 二进制文件已经完成了我给编译器的所有优化。我为该编译过程进行了计时,它用去了 2 分 25 秒的时间,这段时间 足够我去喝咖啡。
不过,我并不希望用这么长时间。我的机器被占用了 2 分 25 秒的时间,而这段时间内它可以做别的一些事情。两分钟看起来也许并 不长,但是 OpenSSH 是一个特别小的应用程序。如果是更大的程序,或者您每天都在进行开发,并且要多次编译代码,那么编译工作每天就会 消耗您几个小时的时间。我是一个忙人,没有那么多可以停工的时间。所以,由于心急,我开始使用 distcc。
distcc 是一个小型应用程序,它与 gcc 编译器是配合使用的,并且它允许在另一台安装了 distcc 的机器上进行编译工作。使用 distcc 的第一步是从 Web 站点(请参见 参考资料 来获得链接)将最新版本的 distcc 下载到您的工作台上。
如果正在使用 SuSE Linux,则可以从 SuSE 得到它们,或者从安装媒体中得到它们;如果正在使用 Gentoo Linux,则可以 运行 emerge distcc
,而 Debian 让我们运行 apt-get install distcc
,而且还提供了一个 FreeBSD 端口,如果您喜欢使用这种方式的话。
对于其他获得 .tar.gz 文件的人(或者那些喜欢 tarball 的人,比如我),可以执行以下操作:
me@mymachine:~/distcc-2.12.1> ./configure --with-gtk
me@mymachine:~/distcc-2.12.1> make
然后,您就成为了超级用户,接下来是安装:
me@mymachine:~/distcc-2.12.1> sudo make install
该过程将安装所有需要文件,distcc 新进程(distccd)应该在 /etc/init.d/distccd 目录中,在启动机器时可以自动启动该进程。如果没有正确将它链接到 rc.d 目录,您可以自己完成这项操作。
我们现在将手工启动这个新进程,而不是重新启动机器去启动它(毕竟,我们 正在 尽力节省我们的时间):
me@mymachine:~/distcc-2.12.1> sudo /etc/init.d/distccd start
值得注意的是,即使没有 root 权限,您也可以运行 distcc 新进程,这一点很棒。在任何启动 distcc 新进程 的机器上,它都只会在您的用户名下运行。
现在,只在一台机器上安装 distcc 是没有意义的;这不会给我们带来任何好处。我打算在我的局域网中找三位 正在使用 Linux 的朋友,看他们是否有兴趣安装 distcc,因为每一个安装 distcc 的人都会从“池(pool)”中受益。
值得注意的是,除了正在使用的 gcc 的版本,机器上通常不需要其他任何公用的东西:它们不需要共享文件系统、 头文件、库或者运行相同的 Linux 内核或发行版本。
这些完成这些操作之后,我需要告诉 distcc 它可以使用哪些机器。我们将这些机器命名为“film”、“flam”和“jabberwocky”。这一次的操作是设置环境变量 DISTCC_HOSTS(这个环境变量也可以放在 ~/.bashrc 中,以便永久使用),我用了 另一个导出操作来完成这项任务:
me@mymachine:~> export DISTCC_HOSTS="mymachine flim flam jabberwocky"
不过,我的机器不如 flim 和 jabberwocky 快,所以我将把它们移到了列表的前面。distccd 的工作原则好像是先到先工作。
me@mymachine:~> export DISTCC_HOSTS="flim jabberwocky mymachine flam"
现在我们应该全部都安排好了。让我们重新对 OpenSSH 进行编译,观察它在三台机器上而不是只在一台机器上运行时的时间花费情况:
me@mymachine:~> cd openssh-3.7p1
因为我们已经为 CFLAGS、 CXXFLAGS和 DISTCC_HOSTS 导出了环境变量 ,所以 我们可以不管不问地继续我们的操作,机器应该会记住我们的设置,除非我们将这些设置放在 ~/.bashrc 中,在这种情况下 它们将自动运行。
现在我们将清除以前的 make 结果,来获得一个干净的环境:
me@mymachine:~/openssh-3.7p1> make clean
开始之前还有另外一件事。distcc 程序自带了一个监视器,通过它我们可以观察哪台机器上正在编译哪个源文件。由 于我们在编译 distcc 时使用了 --use-gtk
选项,所以我们会有两个选择:distccmon-text 和 distccmon-gnome。现在我们将坚持使用控制台版本。启动一个新的终端会话,然后运行:
me@mymachine:~/openssh-3.7p1> distccmon-text 2
您会得到两秒一次的更新。另一种方法(我首选的方法):
me@mymachine:~/openssh-3.7p1> watch distccmon-text
这两种方法或多或少都达到了相同的目的:每两秒钟向您展示一个分布式编译的快照。我们已经完成这项任务, 现在可以运行 configure
。我们需要给 configure 发送一个选项,让它就知道不 要使用普通的 gcc,在没有任何其他指示的情况下,Linux 系统会默认使用它。
me@mymachine:~/openssh-3.7p1> CC=distcc ./configure
当在其他机器上完成配置的一个或两个部分时,distcc 监视器可能会发出‘blip’信号,并伴随少许活动。 完成配置之后,我们就准备好进行实际的编译了:
me@mymachine:~/openssh-3.7p1> make -j 12
我已经将 -j
选项传递给了 make。这不是一个 distcc 特定选项, -j
标志告诉 gcc 一次需要编译多少内容。完全有可能在没有运行 distcc 的机器上 使用 -j
来运行 make,在单 CPU 机器上将 -j
设置为 2 有 时会加快运行速度(但不明显)。不过,我们指定的是 12,表明如果有可能的话,我们将一次同时编译 12 个源文件。
让我们来看一看 distcc 监视器,看它正在做什么:
清单 1. distcc 命令行监视器
5366 Preprocess serve.c flim[0] 5338 Compile minilzo.c flim[1] 5363 Preprocess prefork.c flim[2] 5360 Compile ncpus.c jabberwocky[0] 5352 Compile dparent.c jabberwocky[1] 5356 Compile dsignal.c jabberwocky[2] 5349 Compile dopt.c mymachine[0] 5279 Compile trace.c mymachine[1] 5375 Preprocess srvnet.c mymachine[2] 5342 Compile access.c flam[0] 5346 Compile daemon.c flam[1] 5371 Preprocess setuid.c flam[2]
|
使用 distcc 监视器,我们可以观察到哪个节点上正在编译哪个文件。右边节点名后面的数字指出了它是第n个当前编译文件。在这里,由于我们有四个节点,而且指定 -j
为 12, 所以在每台机器上有三个文件在进行编译。这很有意义,因为在移动所需文件时会有一些网络开销,如果每个节点上 只有一个编译(即 -j 4
),那么 CPU 将会有很多闲置时间。
通过对这些机器进行计时,我得知编译时间缩短了 9 秒,速度提高了大约 16 倍。使用 distcc 进行编译,可以让我利用那些显然比 我的节点快得多的节点,同时还可以让我得到为我个人的工作站而编译并优化的应用程序。
为了观察不同的 -j
值带来的效果,让我们试着改变这些值并重新进行编译:
清单 2. 同步编译数量对编译时间的影响
-j 值 编译时间(秒) 4 19.5 8 10.5 12 8.9 16 8.5 20 8.6
|
我们可以看出,通过改变 -j
的值,可以获得某些好处,不同的配置会 产生不同的结果,但可能还是值得去实验的。另一点需要注意的是,如果您的 distcc 集群中有较多的机器,那么 将您的本地机器从列表中删除会有好处,因为您的机器可能会因为忙于将不同源文件分派到各个机器,同时还要接收编译对象文件而无法负担编译工作。确实如此,将您的本地机器留在列表中可能会使编译过程变慢。
关 于版本还有最后一个注意事项。如果能保持对 distcc 集群中的所有节点使用相同副版本号的 gcc,则 distcc 程序可以获得最佳工作状态;如果这些节点使用的是不同副版本号,则可能会导致编译不稳定,甚至可能导致编译过程完全失败,因为已经修改的部分 gcc 足以产生这样的后果 。例如,如果上面例子中的 mymachine、flim 和 jabberwocky 运行的是 gcc 3.3.1,而 flam 运行的是 gcc 3.2.2,那么 OpenSSH 的编译可能会成功完成,或者可能失败,这取决于在哪台机器上编译哪个部分。要小心, 在这种情况下,即使是成功的编译也可能得不到期望的功能。
最佳策略是坚持使用副版本号相同的 gcc(例如,gcc 3.3.4 和 gcc 3.3.1 都是 gcc 3.3.x,所以它们可以一起用),这样就可以 都又正确又稳定地完成所有编译工作,如果编译失败,也不可能是与 distcc 有关。
那么,我们来总结一下这个过程:
- 在所有您想用来编译的机器上安装 distcc
- 启动每台机器上的 distcc 新进程
- 用变量名导出 DISTCC_HOSTS 环境变量
- 启动 distcc 监视器(这样就可以观察正在发生什么事!)
- 使用
CC=distcc ./configure
,而不是使用 ./configure
来进行配置
- 使用
make -j n
,而不是使用 make
或 make -j 2
来进行编译,其中,n 是 DISTCC_HOSTS中机器数目的两到三倍
如果您有从优化中受益的程序,那么从源代码中“构造您自己的(rolling your own)”二进制则是您应该选择的方式。 当进行大规模编译时,就所需要的最大执行时间(wall-clock time)而言,这样做的代价可能会比较高,而使用 distcc 能让您(和所有 其他人)充分利用网络上的闲置 CPU 周期,尽可能快地建立和运行您的程序。
关于作者
|
|
|
Laurence Bonney 是英国 IBM Hursley 实验室的一名软件工程师。他是致力于 WebSphere MQ JMS 产品的测试小组的技术小组领导人。在业余时间,他喜欢弹吉他(尽管弹得很糟),会尽可能利用假期去冲浪,还喜欢玩视频游戏。您可以通过 bonneyl@uk.ibm.com与 Laurence 联系。
|
分享到:
相关推荐
distcc-2.18.3 分布式编译工具 distcc-2.18.3 分布式编译工具
例如,在一台机器上编译一个大型项目,使用 distcc 可以将编译时间从 42 分钟减少到 17 分钟。 distcc 是一种非常有用的工具,可以帮助我们加速编译速度,提高开发效率。但是,在使用 distcc 时需要注意版本问题和...
这种模式充分利用了多台机器的计算资源,大大缩短了整体编译时间。 在distcc 2.18.3中,开发者可以期待以下关键特性: 1. **性能优化**:这一版本对网络通信进行了优化,减少了数据传输的时间开销,从而提高了整体...
为了解决这个问题,分布式编译工具应运而生,其中distcc(Distributed C/C++ Compiler)是一款广泛使用的开源工具,它能够将编译任务分散到多台计算机上并行处理,显著提高编译速度。本文将详细解析distcc的最新版本...
结合使用`distcc`与`ccache`(一种缓存编译结果以加速后续编译的工具),可以让重复的软件包构建过程变得非常迅速。 #### 设计原理 `distcc`的核心设计理念是实现一个轻量级且易于使用的分布式编译系统。它通过...
Linux程序编译速度提高方法 使用distcc和ccache缩短C/C++项目编译时间 如何让 Xcode 在读写上提速100倍? 全民K歌后台编译优化:从40分钟到30秒 编译环境+工程放在内存虚拟的硬盘里比机械硬盘运行速度提升不少
3. **分布式编译**:对于非常大的项目,可以使用如DistCC或Jenkins等工具,将编译任务分发到网络中的多台机器上,实现跨机器的并行编译。 4. **预编译头文件(Precompiled Header, PCH)**:PCH是另一种提高编译...
Icecream 是由 SUSE 创建的、基于 distcc 的并行编译工具。可在远程机器上执行构建和分发、并行编译。与 distcc 不同的是,Icecream 使用一个中央服务器动态的对编译作业进行调度。 标签:Icecream
distcc_detection
distcc通过网络将源代码的编译任务分发到多台计算机上并行处理,从而显著减少大型项目的编译时间。其核心思想是利用闲置的计算资源,将编译工作负载分散到多台机器上,每台机器处理一部分任务,然后将结果汇总。这...
distcc应该始终产生与本地编译相同的结果,易于安装和使用,并且通常比本地编译快两倍或更多倍。 与其他分布式构建系统不同,distcc不需要所有机器共享文件系统,具有同步时钟或安装相同的库或头文件。 机器可以...
但是与distcc不同, 使用中央服务器动态地将编译作业调度到最快的免费服务器。 这种优势主要为共享计算机带来了回报,如果您是x机上的唯一用户,则可以完全控制它们。 目录-Werror构建仅在使用冰淇淋时失败clang ...
distccForXCode 使 distcc 在 XCode 中工作 客户端:quick_client.sh 服务器:quick_server.sh 如果你不想使用它,:restoreLLVM.sh
distcc应该始终产生与本地编译相同的结果,易于安装和使用,并且通常比本地编译快两倍或更多倍。 与其他分布式构建系统不同,distcc不需要所有机器共享文件系统,具有同步时钟或安装相同的库或头文件。 机器可以运行...
通过将编译任务分散到多台机器上,Distcc可以显著提升整体编译速度,尤其在处理大型或复杂项目时效果更为明显。 Gentoo Linux是基于Portage包管理系统的一个源代码级别的Linux发行版,它允许用户根据自己的硬件配置...
Distcc则是一个开源的解决方案,允许开发者在多台计算机之间分发编译任务,降低了大型项目在单一机器上的编译时间。两者都利用了分布式计算的优势,但Incredibuilder通常提供更高级的功能和更友好的用户界面。 ...
自动设置并使用distcc加快编译速度(如果启用)。如果构建的软件包具有必须也要构建的依赖关系(即Arch仓库中没有的依赖关系),则管理本地仓库是有帮助的。差异化的另一个关键点是ccm可以使用distcc来构建软件包。...
DistccTracker是一款基于Java开发的开源工具,专为Distcc分布式编译系统设计的服务器跟踪器。Distcc(Distributed C/C++ Compiler)是一个能够将编译任务分发到网络中多台计算机的系统,从而加快编译速度,提高开发...
例如,使用Ccache和Distcc来加快代码编译过程,这对于开发者而言是非常有用的技巧,尤其是当进行大规模编译时,可以大大减少等待时间。另外,文档中还提到了如何通过Conman以及FBSched同步Gazebo模拟与实际硬件之间...