367 lines
18 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Using DistCC to speed up compilation</title>
<script type="text/javascript" src="_static/js/modernizr.min.js"></script>
<script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/language_data.js"></script>
<script type="text/javascript" src="_static/js/theme.js"></script>
<link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search" >
<a href="index.html" class="icon icon-home"> Point Cloud Library
</a>
<div class="version">
1.12.0
</div>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="search.html" method="get">
<input type="text" name="q" placeholder="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
<!-- Local TOC -->
<div class="local-toc"><ul>
<li><a class="reference internal" href="#">Using DistCC to speed up compilation</a></li>
</ul>
</div>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
<nav class="wy-nav-top" aria-label="top navigation">
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="index.html">Point Cloud Library</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="breadcrumbs navigation">
<ul class="wy-breadcrumbs">
<li><a href="index.html">Docs</a> &raquo;</li>
<li>Using DistCC to speed up compilation</li>
<li class="wy-breadcrumbs-aside">
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<div class="section" id="using-distcc-to-speed-up-compilation">
<span id="distc"></span><h1>Using DistCC to speed up compilation</h1>
<p><a class="reference external" href="http://distcc.org/">distcc</a> is a program to distribute builds of C, C++,
Objective C or Objective C++ code across several machines on a network.
<cite>distcc</cite> should always generate the same results as a local build, is simple to
install and use, and is usually much faster than a local compile.</p>
<p><cite>distcc</cite> does not require all machines to share a filesystem, have synchronized
clocks, or to have the same libraries or header files installed. They can even
have different processors or operating systems, if cross-compilers are
installed.</p>
<p><cite>distcc</cite> is usually very easy to install just follow the installation
instructions on its web page. Heres an example for Ubuntu systems:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">sudo</span> <span class="n">apt</span><span class="o">-</span><span class="n">get</span> <span class="n">install</span> <span class="n">distcc</span>
</pre></div>
</div>
<p>In each distributed build environment, there are usually two different roles:</p>
<blockquote>
<div><ul>
<li><p class="first"><strong>server</strong></p>
<p>Here, we call the <em>server</em>, the actual workstation/computer that is running
a <cite>distcc</cite> daemon, and will perform the compilation. To run a <cite>distcc</cite>
daemon on an Ubuntu system for example, you need to start the daemon,
usually with something along the lines of:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">/</span><span class="n">etc</span><span class="o">/</span><span class="n">init</span><span class="o">.</span><span class="n">d</span><span class="o">/</span><span class="n">distcc</span> <span class="n">start</span>
</pre></div>
</div>
<p>Once started, you should notice a few <cite>distcc</cite> processes idle-ing:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ ps axw | grep distcc
...
30042 ? SN 0:00 /usr/bin/distccd --pid-file=/var/run/distccd.pid --log-file=/var/log/distccd.log --daemon --allow 127.0.0.1 --allow 10.0.0.0/21 --listen 0.0.0.0 --nice 10 --zeroconf
30043 ? SN 0:00 /usr/bin/distccd --pid-file=/var/run/distccd.pid --log-file=/var/log/distccd.log --daemon --allow 127.0.0.1 --allow 10.0.0.0/21 --listen 0.0.0.0 --nice 10 --zeroconf
30044 ? SN 0:00 /usr/bin/distccd --pid-file=/var/run/distccd.pid --log-file=/var/log/distccd.log --daemon --allow 127.0.0.1 --allow 10.0.0.0/21 --listen 0.0.0.0 --nice 10 --zeroconf
</pre></div>
</div>
<p>Lets assume for the sake of this example, that we have two machines,
<em>wgsc11</em> and <em>wgsc12</em>, with <cite>distcc</cite> installed and running as a server
daemon. These are the machines that we would like use to speed up the
compilation of the PCL source tree.</p>
</li>
<li><p class="first"><strong>client</strong></p>
<p>Here by client we refer to the workstation/computer that contains the source
code to be compiled, in our case, where the PCL source code tree resides.</p>
<p>The first thing that we need to do is tell <cite>cmake</cite> to use <cite>distcc</cite> instead
of the default compiler. The easiest way to do this is to invoke <cite>cmake</cite>
with pre-flags, like:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>[pcl] $ mkdir build &amp;&amp; cd build
[pcl/build] $ CC=&quot;distcc gcc&quot; CXX=&quot;distcc g++&quot; cmake ..
</pre></div>
</div>
<p>Sometimes compiling on systems supporting different SSE extensions will lead
to problems. Setting PCL_ENABLE_SSE to false will solve this, like:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>[pcl/build] $ CC=&quot;distcc gcc&quot; CXX=&quot;distcc g++&quot; cmake -DPCL_ENABLE_SSE:BOOL=FALSE ../pcl
</pre></div>
</div>
<p>The output of <code class="docutils literal notranslate"><span class="pre">CC=&quot;distcc</span> <span class="pre">gcc&quot;</span> <span class="pre">CXX=&quot;distcc</span> <span class="pre">g++&quot;</span> <span class="pre">cmake</span> <span class="pre">..</span></code> will generate
something like this. Please note that this is just an example and that the
messages might vary depending on your operating system and the way your
library dependencies were compiled/installed:</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>-- The C compiler identification is GNU
-- The CXX compiler identification is GNU
-- Check <span class="k">for</span> working C compiler: /usr/bin/distcc
-- Check <span class="k">for</span> working C compiler: /usr/bin/distcc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - <span class="k">done</span>
-- Check <span class="k">for</span> working CXX compiler: /usr/bin/distcc
-- Check <span class="k">for</span> working CXX compiler: /usr/bin/distcc -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - <span class="k">done</span>
-- Performing Test HAVE_SSE3_EXTENSIONS
-- Performing Test HAVE_SSE3_EXTENSIONS - Success
-- Performing Test HAVE_SSE2_EXTENSIONS
-- Performing Test HAVE_SSE2_EXTENSIONS - Success
-- Performing Test HAVE_SSE_EXTENSIONS
-- Performing Test HAVE_SSE_EXTENSIONS - Success
-- Found SSE3 extensions, using flags: -msse3 -mfpmath<span class="o">=</span>sse
-- Boost version: <span class="m">1</span>.42.0
-- Found the following Boost libraries:
-- system
-- filesystem
-- thread
-- date_time
-- iostreams
-- checking <span class="k">for</span> module <span class="s1">&#39;eigen3&#39;</span>
-- found eigen3, version <span class="m">3</span>.0.0
-- Found Eigen: /usr/include/eigen3
-- Eigen found <span class="o">(</span>include: /usr/include/eigen3<span class="o">)</span>
-- checking <span class="k">for</span> module <span class="s1">&#39;flann&#39;</span>
-- found flann, version <span class="m">1</span>.6.8
-- Found Flann: /usr/lib64/libflann_cpp_s.a
-- FLANN found <span class="o">(</span>include: /usr/include, lib: optimized<span class="p">;</span>/usr/lib64/libflann_cpp_s.a<span class="p">;</span>debug<span class="p">;</span>/usr/lib64/libflann_cpp.so<span class="o">)</span>
-- checking <span class="k">for</span> module <span class="s1">&#39;cminpack&#39;</span>
-- found cminpack, version <span class="m">1</span>.0.90
-- Found CMinpack: /usr/lib64/libcminpack.so
-- CMinPack found <span class="o">(</span>include: /usr/include/cminpack-1, libs: optimized<span class="p">;</span>/usr/lib64/libcminpack.so<span class="p">;</span>debug<span class="p">;</span>/usr/lib64/libcminpack.so<span class="o">)</span>
-- Try OpenMP C <span class="nv">flag</span> <span class="o">=</span> <span class="o">[</span>-fopenmp<span class="o">]</span>
-- Performing Test OpenMP_FLAG_DETECTED
-- Performing Test OpenMP_FLAG_DETECTED - Success
-- Try OpenMP CXX <span class="nv">flag</span> <span class="o">=</span> <span class="o">[</span>-fopenmp<span class="o">]</span>
-- Performing Test OpenMP_FLAG_DETECTED
-- Performing Test OpenMP_FLAG_DETECTED - Success
-- Found OpenMP: -fopenmp
-- Found OpenNI: /usr/lib/libOpenNI.so
-- OpenNI found <span class="o">(</span>include: /usr/include/openni, lib: /usr/lib/libOpenNI.so<span class="o">)</span>
-- ROS_ROOT /opt/ros/diamondback/ros
-- Found ROS<span class="p">;</span> USE_ROS is OFF
-- Found GTest: /usr/lib/libgtest.so
-- Tests will be built
-- Found Qhull: /usr/lib/libqhull.so
-- QHULL found <span class="o">(</span>include: /usr/include/qhull, lib: optimized<span class="p">;</span>/usr/lib/libqhull.so<span class="p">;</span>debug<span class="p">;</span>/usr/lib/libqhull.so<span class="o">)</span>
-- VTK found <span class="o">(</span>include: /usr/include/vtk-5.4<span class="p">;</span>/usr/include<span class="p">;</span>/usr/include<span class="p">;</span>/usr/include<span class="p">;</span>/usr/include<span class="p">;</span>/usr/include<span class="p">;</span>/usr/include<span class="p">;</span>/usr/include<span class="p">;</span>/usr/include<span class="p">;</span>/usr/include<span class="p">;</span>/usr/include<span class="p">;</span>/usr/include<span class="p">;</span>/usr/include<span class="p">;</span>/usr/include<span class="p">;</span>/usr/include<span class="p">;</span>/usr/include<span class="p">;</span>/usr/include<span class="p">;</span>/usr/include<span class="p">;</span>/usr/include<span class="p">;</span>/usr/include<span class="p">;</span>/usr/lib/openmpi/include<span class="p">;</span>/usr/lib/openmpi/include/openmpi<span class="p">;</span>/usr/include/tcl8.5<span class="p">;</span>/usr/include/python2.6<span class="p">;</span>/usr/include/tcl8.5<span class="p">;</span>/usr/lib/jvm/default-java/include<span class="p">;</span>/usr/lib/jvm/default-java/include<span class="p">;</span>/usr/lib/jvm/default-java/include<span class="p">;</span>/usr/include<span class="p">;</span>/usr/include<span class="p">;</span>/usr/include<span class="p">;</span>/usr/include<span class="p">;</span>/usr/include<span class="p">;</span>/usr/include/libxml2<span class="p">;</span>/usr/include<span class="p">;</span>/usr/include/freetype2, lib: /usr/lib/vtk-5.4<span class="o">)</span>
-- Found Doxygen: /usr/bin/doxygen
-- Found CPack generators: DEB
-- The following subsystems will be built:
-- common
-- octree
-- io
-- kdtree
-- range_image
-- features
-- sample_consensus
-- keypoints
-- filters
-- registration
-- segmentation
-- surface
-- visualization
-- global_tests
-- The following subsystems will not be built:
-- Configuring <span class="k">done</span>
-- Generating <span class="k">done</span>
-- Build files have been written to: /work/PCL/pcl/trunk/build
</pre></div>
</div>
</li>
</ul>
<blockquote>
<div><p>The important lines are:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">--</span> <span class="n">Check</span> <span class="k">for</span> <span class="n">working</span> <span class="n">C</span> <span class="n">compiler</span><span class="p">:</span> <span class="o">/</span><span class="n">usr</span><span class="o">/</span><span class="nb">bin</span><span class="o">/</span><span class="n">distcc</span>
<span class="o">--</span> <span class="n">Check</span> <span class="k">for</span> <span class="n">working</span> <span class="n">C</span> <span class="n">compiler</span><span class="p">:</span> <span class="o">/</span><span class="n">usr</span><span class="o">/</span><span class="nb">bin</span><span class="o">/</span><span class="n">distcc</span> <span class="o">--</span> <span class="n">works</span>
<span class="o">--</span> <span class="n">Detecting</span> <span class="n">C</span> <span class="n">compiler</span> <span class="n">ABI</span> <span class="n">info</span>
<span class="o">--</span> <span class="n">Detecting</span> <span class="n">C</span> <span class="n">compiler</span> <span class="n">ABI</span> <span class="n">info</span> <span class="o">-</span> <span class="n">done</span>
<span class="o">--</span> <span class="n">Check</span> <span class="k">for</span> <span class="n">working</span> <span class="n">CXX</span> <span class="n">compiler</span><span class="p">:</span> <span class="o">/</span><span class="n">usr</span><span class="o">/</span><span class="nb">bin</span><span class="o">/</span><span class="n">distcc</span>
<span class="o">--</span> <span class="n">Check</span> <span class="k">for</span> <span class="n">working</span> <span class="n">CXX</span> <span class="n">compiler</span><span class="p">:</span> <span class="o">/</span><span class="n">usr</span><span class="o">/</span><span class="nb">bin</span><span class="o">/</span><span class="n">distcc</span> <span class="o">--</span> <span class="n">works</span>
</pre></div>
</div>
<p>The next step is to tell <cite>distcc</cite> which hosts it should use. Here we can
decide whether we want to use the local workstation for compilation too, or
just the machines running a <cite>distcc</cite> daemon (<em>wgsc11</em> and <em>wgsc12</em> in our
example). The easiest way to pass this information to <cite>distcc</cite> is via
environment variables. For example:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">export</span> <span class="n">DISTCC_HOSTS</span><span class="o">=</span><span class="s1">&#39;localhost wgsc11 wgsc12&#39;</span>
</pre></div>
</div>
<p>will tell <cite>distcc</cite> to use the local machine, as well as both the <cite>distcc</cite>
servers, while:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">export</span> <span class="n">DISTCC_HOSTS</span><span class="o">=</span><span class="s1">&#39;wgsc11 wgsc12&#39;</span>
</pre></div>
</div>
<p>will only use the <em>wgsc11</em> and <em>wgsc12</em> machines.</p>
<p>Finally, the last step is to increase the number of parallel compile units we should use. For example:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>[pcl/build] $ make -j32
</pre></div>
</div>
<p>will start <strong>32 processes</strong> and distribute them equally on the two <cite>distcc</cite> machines.</p>
</div></blockquote>
</div></blockquote>
<p>The following plot shows an example of multiple <code class="docutils literal notranslate"><span class="pre">make</span> <span class="pre">-jX</span></code> invocations, for X
ranging from 1 to 13. As it can be seen, the overall compile time is
drastically reduced by using <cite>distcc</cite>, in this case with the CPU on the client
machine almost idleing while the <em>wgsc11</em> and <em>wgsc12</em> machines do most of the
work. The reason why the plot “saturates” is due to conditional dependencies in
the compilation process, where certain libraries or binaries require others to
be compiled first.</p>
<img alt="_images/distcc_plot.png" src="_images/distcc_plot.png" />
<p>For more information on how to configure <cite>distcc</cite> please visit <a class="reference external" href="http://distcc.org">http://distcc.org</a>.</p>
</div>
</div>
</div>
<footer>
<hr/>
<div role="contentinfo">
<p>
&copy; Copyright
</p>
</div>
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<script type="text/javascript">
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>