1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-26 07:11:34 -08:00
emacs/mps/manual/html/guide/perf.html
Richard Brooksby 8c4a4b127d Updated manual html
Copied from Perforce
 Change: 181622
 ServerID: perforce.ravenbrook.com
2013-05-08 14:07:56 +01:00

447 lines
No EOL
13 KiB
HTML

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>5. Tuning the Memory Pool System for performance &mdash; Memory Pool System 1.111.0 documentation</title>
<link rel="stylesheet" href="../_static/mps.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '../',
VERSION: '1.111.0',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</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>
<link rel="copyright" title="Copyright" href="../copyright.html" />
<link rel="top" title="Memory Pool System 1.111.0 documentation" href="../index.html" />
<link rel="up" title="Guide" href="index.html" />
<link rel="next" title="6. Advanced topics" href="advanced.html" />
<link rel="prev" title="4. Debugging with the Memory Pool System" href="debug.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="advanced.html" title="6. Advanced topics"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="debug.html" title="4. Debugging with the Memory Pool System"
accesskey="P">previous</a> |</li>
<li><a href="../index.html">Memory Pool System 1.111.0 documentation</a> &raquo;</li>
<li><a href="index.html" accesskey="U">Guide</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="tuning-the-memory-pool-system-for-performance">
<span id="guide-perf"></span><span id="index-0"></span><h1>5. Tuning the Memory Pool System for performance<a class="headerlink" href="#tuning-the-memory-pool-system-for-performance" title="Permalink to this headline"></a></h1>
<div class="admonition-note admonition">
<p class="first admonition-title">Note</p>
<p class="last">When developing a benchmark to profile your program against, bear
in mind that the benchmark should allocate several times the
amount of physical memory that you expect to be available to the
process. If the total allocation fits into the available memory,
there&#8217;s no point running a garbage collector at all: you might as
well just allocate and never collect.</p>
</div>
<p>The most important aspect of tuning the MPS is to choose good sizes
for the <a class="reference internal" href="../glossary/g.html#term-generation"><em class="xref std std-term">generations</em></a> in your <a class="reference internal" href="../glossary/g.html#term-generation-chain"><em class="xref std std-term">generation chain</em></a>. The
ideal size of a generation should be such that when it is collected,
most of the blocks allocated in that generation should be found to be
<a class="reference internal" href="../glossary/d.html#term-dead"><em class="xref std std-term">dead</em></a> (and so the cost of <a class="reference internal" href="../glossary/s.html#term-scan"><em class="xref std std-term">scanning</em></a> and
<a class="reference internal" href="../glossary/c.html#term-copying-garbage-collection"><em class="xref std std-term">copying</em></a> them can be avoided
entirely). If a generation is collected when its blocks are mostly
alive, that is a waste of time.</p>
<p>In the tables below I give the execution time of <tt class="docutils literal"><span class="pre">test-leaf.scm</span></tt> in
the toy Scheme interpreter under different settings for its generation
chain. (This test case allocates hundreds of millions of small
short-lived objects.)</p>
<p>First, the effect of varying the capacity of a chain with a single
generation.</p>
<table border="1" class="docutils">
<colgroup>
<col width="19%" />
<col width="21%" />
<col width="60%" />
</colgroup>
<thead valign="bottom">
<tr class="row-odd"><th class="head">Capacity</th>
<th class="head">Mortality</th>
<th class="head">Execution time (user+sys)</th>
</tr>
</thead>
<tbody valign="top">
<tr class="row-even"><td>100</td>
<td>0.80</td>
<td>362.6</td>
</tr>
<tr class="row-odd"><td>200</td>
<td>0.80</td>
<td>354.9</td>
</tr>
<tr class="row-even"><td>400</td>
<td>0.80</td>
<td>349.7</td>
</tr>
<tr class="row-odd"><td>800</td>
<td>0.80</td>
<td>314.4</td>
</tr>
<tr class="row-even"><td>1600</td>
<td>0.80</td>
<td>215.7</td>
</tr>
<tr class="row-odd"><td>3200</td>
<td>0.80</td>
<td>94.0</td>
</tr>
<tr class="row-even"><td>6400</td>
<td>0.80</td>
<td>53.5</td>
</tr>
<tr class="row-odd"><td>12800</td>
<td>0.80</td>
<td>79.6</td>
</tr>
<tr class="row-even"><td>25600</td>
<td>0.80</td>
<td>77.6</td>
</tr>
</tbody>
</table>
<p>Second, the effect of varying the mortality of a chain with a single
generation.</p>
<table border="1" class="docutils">
<colgroup>
<col width="19%" />
<col width="21%" />
<col width="60%" />
</colgroup>
<thead valign="bottom">
<tr class="row-odd"><th class="head">Capacity</th>
<th class="head">Mortality</th>
<th class="head">Execution time (user+sys)</th>
</tr>
</thead>
<tbody valign="top">
<tr class="row-even"><td>6400</td>
<td>0.20</td>
<td>55.4</td>
</tr>
<tr class="row-odd"><td>6400</td>
<td>0.40</td>
<td>54.0</td>
</tr>
<tr class="row-even"><td>6400</td>
<td>0.60</td>
<td>54.0</td>
</tr>
<tr class="row-odd"><td>6400</td>
<td>0.80</td>
<td>53.5</td>
</tr>
<tr class="row-even"><td>6400</td>
<td>0.99</td>
<td>54.8</td>
</tr>
</tbody>
</table>
<p>Third, the effect of varying the number of generations (all
generations being identical).</p>
<table border="1" class="docutils">
<colgroup>
<col width="21%" />
<col width="15%" />
<col width="17%" />
<col width="47%" />
</colgroup>
<thead valign="bottom">
<tr class="row-odd"><th class="head">Generations</th>
<th class="head">Capacity</th>
<th class="head">Mortality</th>
<th class="head">Execution time (user+sys)</th>
</tr>
</thead>
<tbody valign="top">
<tr class="row-even"><td>1</td>
<td>6400</td>
<td>0.80</td>
<td>53.5</td>
</tr>
<tr class="row-odd"><td>2</td>
<td>6400</td>
<td>0.80</td>
<td>42.4</td>
</tr>
<tr class="row-even"><td>3</td>
<td>6400</td>
<td>0.80</td>
<td>42.1</td>
</tr>
<tr class="row-odd"><td>4</td>
<td>6400</td>
<td>0.80</td>
<td>42.2</td>
</tr>
<tr class="row-even"><td>5</td>
<td>6400</td>
<td>0.80</td>
<td>42.2</td>
</tr>
</tbody>
</table>
<p>These tables suggest that:</p>
<ol class="arabic simple">
<li>The improvement in performance to be gained by getting generation
sizes right is dramatic: much bigger than the small improvements to
gained from other techniques.</li>
<li>The predicted mortality doesn&#8217;t make much difference to the overall
execution time (it does affect the distribution of pause times,
however: see <a class="reference internal" href="../topic/collection.html#topic-collection-schedule"><em>Scheduling of collections</em></a>.)</li>
<li>You can make generations too big as well as too small.</li>
<li>There are rapidly diminishing returns to be gained from adding
generations.</li>
</ol>
<div class="admonition-note admonition">
<p class="first admonition-title">Note</p>
<p class="last"><a class="reference internal" href="../topic/telemetry.html#topic-telemetry"><em>Telemetry</em></a> can be used to discover when generations
are being collected and what proportion of blocks were found to be
alive.</p>
</div>
<p>The table below shows the effect of varying the initial allocation of
address space to the arena (using three generations each with capacity
6400 kB, mortality 0.80).</p>
<table border="1" class="docutils">
<colgroup>
<col width="22%" />
<col width="17%" />
<col width="19%" />
<col width="42%" />
</colgroup>
<thead valign="bottom">
<tr class="row-odd"><th class="head">Address space</th>
<th class="head">Extensions</th>
<th class="head">Collections</th>
<th class="head">Execution time (user+sys)</th>
</tr>
</thead>
<tbody valign="top">
<tr class="row-even"><td>2</td>
<td>32</td>
<td>371</td>
<td>52.0</td>
</tr>
<tr class="row-odd"><td>4</td>
<td>21</td>
<td>370</td>
<td>47.0</td>
</tr>
<tr class="row-even"><td>8</td>
<td>0</td>
<td><a class="footnote-reference" href="#id5" id="id1">[1]</a></td>
<td><a class="footnote-reference" href="#id5" id="id2">[1]</a></td>
</tr>
<tr class="row-odd"><td>14</td>
<td>0</td>
<td><a class="footnote-reference" href="#id5" id="id3">[1]</a></td>
<td><a class="footnote-reference" href="#id5" id="id4">[1]</a></td>
</tr>
<tr class="row-even"><td>16</td>
<td>0</td>
<td>2436</td>
<td>160.5</td>
</tr>
<tr class="row-odd"><td>18</td>
<td>0</td>
<td>1135</td>
<td>89.1</td>
</tr>
<tr class="row-even"><td>20</td>
<td>0</td>
<td>673</td>
<td>60.6</td>
</tr>
<tr class="row-odd"><td>22</td>
<td>0</td>
<td>484</td>
<td>48.7</td>
</tr>
<tr class="row-even"><td>24</td>
<td>0</td>
<td>400</td>
<td>43.1</td>
</tr>
<tr class="row-odd"><td>32</td>
<td>0</td>
<td>368</td>
<td>41.2</td>
</tr>
<tr class="row-even"><td>64</td>
<td>0</td>
<td>368</td>
<td>43.1</td>
</tr>
<tr class="row-odd"><td>128</td>
<td>0</td>
<td>368</td>
<td>46.4</td>
</tr>
<tr class="row-even"><td>256</td>
<td>0</td>
<td>368</td>
<td>46.3</td>
</tr>
<tr class="row-odd"><td>512</td>
<td>0</td>
<td>368</td>
<td>49.3</td>
</tr>
<tr class="row-even"><td>1024</td>
<td>0</td>
<td>368</td>
<td>42.0</td>
</tr>
<tr class="row-odd"><td>2048</td>
<td>0</td>
<td>368</td>
<td>43.2</td>
</tr>
<tr class="row-even"><td>4096</td>
<td>0</td>
<td>368</td>
<td>43.5</td>
</tr>
<tr class="row-odd"><td>8192</td>
<td>0</td>
<td>368</td>
<td>46.1</td>
</tr>
<tr class="row-even"><td>16384</td>
<td>0</td>
<td>368</td>
<td>49.2</td>
</tr>
<tr class="row-odd"><td>32768</td>
<td>0</td>
<td>368</td>
<td>57.1</td>
</tr>
<tr class="row-even"><td>65536</td>
<td>0</td>
<td>368</td>
<td>71.1</td>
</tr>
<tr class="row-odd"><td>131072</td>
<td>0</td>
<td>368</td>
<td>101.3</td>
</tr>
<tr class="row-even"><td>262144</td>
<td>0</td>
<td>368</td>
<td>161.3</td>
</tr>
<tr class="row-odd"><td>524288</td>
<td>0</td>
<td>368</td>
<td>273.0</td>
</tr>
<tr class="row-even"><td>1048576</td>
<td>0</td>
<td>368</td>
<td>504.6</td>
</tr>
</tbody>
</table>
<div class="admonition-note admonition">
<p class="first admonition-title">Note</p>
<table class="last docutils footnote" frame="void" id="id5" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label">[1]</td><td><em>(<a class="fn-backref" href="#id1">1</a>, <a class="fn-backref" href="#id2">2</a>, <a class="fn-backref" href="#id3">3</a>, <a class="fn-backref" href="#id4">4</a>)</em> With this initial allocation of address space, the test
case failed to run to completion after thousands of seconds
and tens of thousands of garbage collection cycles.</td></tr>
</tbody>
</table>
</div>
<p>The lesson here is that the allocation of address space has to be
comfortably larger than the working set of the program, but that a
very large address space is ruinous to performance.</p>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<p class="logo"><a href="../index.html">
<img class="logo" src="../_static/logo.png" alt="Logo"/>
</a></p>
<h4>Previous topic</h4>
<p class="topless"><a href="debug.html"
title="previous chapter">4. Debugging with the Memory Pool System</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="advanced.html"
title="next chapter">6. Advanced topics</a></p><h4>Downloads</h4>
<p class="topless">
<a href="http://www.ravenbrook.com/project/mps/release/1.111.0/">MPS Kit release 1.111.0</a><br>
<a href="http://www.ravenbrook.com/project/mps/release/">All MPS Kit releases</a>
</p>
<h4>Issues</h4>
<p class="topless">
<a href="http://www.ravenbrook.com/project/mps/issue/?action=list&amp;view=status%3dopen&amp;display=Job:Priority:Title&amp;sort=Priority">Known issues</a><br>
<a href="http://www.ravenbrook.com/project/mps/issue/?action=fixed&release_fixed=1.111.0">Issues fixed in release 1.111.0</a>
</p><h4>Contact us</h4>
<p class="topless"><a href="mailto:mps-questions@ravenbrook.com">mps-questions@ravenbrook.com</a></p>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="advanced.html" title="6. Advanced topics"
>next</a> |</li>
<li class="right" >
<a href="debug.html" title="4. Debugging with the Memory Pool System"
>previous</a> |</li>
<li><a href="../index.html">Memory Pool System 1.111.0 documentation</a> &raquo;</li>
<li><a href="index.html" >Guide</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; <a href="../copyright.html">Copyright</a> 2013, Ravenbrook Limited.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>