Sophie

Sophie

distrib > Mageia > 7 > armv7hl > media > core-release > by-pkgid > 0c2243f8a1696816431e7210e991fa52 > files > 12790

rust-doc-1.35.0-1.mga7.armv7hl.rpm

<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js">
    <head>
        <!-- Book generated using mdBook -->
        <meta charset="UTF-8">
        <title>Optimizations: The speed size tradeoff - The Embedded Rust Book</title>
        <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="theme-color" content="#ffffff" />

        <link rel="shortcut icon" href="../favicon.png">
        <link rel="stylesheet" href="../css/variables.css">
        <link rel="stylesheet" href="../css/general.css">
        <link rel="stylesheet" href="../css/chrome.css">
        <link rel="stylesheet" href="../css/print.css" media="print">

        <!-- Fonts -->
        <link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
        <link href="https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800" rel="stylesheet" type="text/css">
        <link href="https://fonts.googleapis.com/css?family=Source+Code+Pro:500" rel="stylesheet" type="text/css">

        <!-- Highlight.js Stylesheets -->
        <link rel="stylesheet" href="../highlight.css">
        <link rel="stylesheet" href="../tomorrow-night.css">
        <link rel="stylesheet" href="../ayu-highlight.css">

        <!-- Custom theme stylesheets -->
        

        
    </head>
    <body class="light">
        <!-- Provide site root to javascript -->
        <script type="text/javascript">
            var path_to_root = "../";
            var default_theme = "light";
        </script>

        <!-- Work around some values being stored in localStorage wrapped in quotes -->
        <script type="text/javascript">
            try {
                var theme = localStorage.getItem('mdbook-theme');
                var sidebar = localStorage.getItem('mdbook-sidebar');

                if (theme.startsWith('"') && theme.endsWith('"')) {
                    localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
                }

                if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
                    localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
                }
            } catch (e) { }
        </script>

        <!-- Set the theme before any content is loaded, prevents flash -->
        <script type="text/javascript">
            var theme;
            try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { } 
            if (theme === null || theme === undefined) { theme = default_theme; }
            document.body.className = theme;
            document.querySelector('html').className = theme + ' js';
        </script>

        <!-- Hide / unhide sidebar before it is displayed -->
        <script type="text/javascript">
            var html = document.querySelector('html');
            var sidebar = 'hidden';
            if (document.body.clientWidth >= 1080) {
                try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
                sidebar = sidebar || 'visible';
            }
            html.classList.remove('sidebar-visible');
            html.classList.add("sidebar-" + sidebar);
        </script>

        <nav id="sidebar" class="sidebar" aria-label="Table of contents">
            <ol class="chapter"><li><a href="../intro/index.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><ol class="section"><li><a href="../intro/hardware.html"><strong aria-hidden="true">1.1.</strong> Hardware</a></li><li><a href="../intro/no-std.html"><strong aria-hidden="true">1.2.</strong> no_std</a></li><li><a href="../intro/tooling.html"><strong aria-hidden="true">1.3.</strong> Tooling</a></li><li><a href="../intro/install.html"><strong aria-hidden="true">1.4.</strong> Installation</a></li><li><ol class="section"><li><a href="../intro/install/linux.html"><strong aria-hidden="true">1.4.1.</strong> Linux</a></li><li><a href="../intro/install/macos.html"><strong aria-hidden="true">1.4.2.</strong> MacOS</a></li><li><a href="../intro/install/windows.html"><strong aria-hidden="true">1.4.3.</strong> Windows</a></li><li><a href="../intro/install/verify.html"><strong aria-hidden="true">1.4.4.</strong> Verify Installation</a></li></ol></li></ol></li><li><a href="../start/index.html"><strong aria-hidden="true">2.</strong> Getting started</a></li><li><ol class="section"><li><a href="../start/qemu.html"><strong aria-hidden="true">2.1.</strong> QEMU</a></li><li><a href="../start/hardware.html"><strong aria-hidden="true">2.2.</strong> Hardware</a></li><li><a href="../start/registers.html"><strong aria-hidden="true">2.3.</strong> Memory-mapped Registers</a></li><li><a href="../start/semihosting.html"><strong aria-hidden="true">2.4.</strong> Semihosting</a></li><li><a href="../start/panicking.html"><strong aria-hidden="true">2.5.</strong> Panicking</a></li><li><a href="../start/exceptions.html"><strong aria-hidden="true">2.6.</strong> Exceptions</a></li><li><a href="../start/interrupts.html"><strong aria-hidden="true">2.7.</strong> Interrupts</a></li><li><a href="../start/io.html"><strong aria-hidden="true">2.8.</strong> IO</a></li></ol></li><li><a href="../peripherals/index.html"><strong aria-hidden="true">3.</strong> Peripherals</a></li><li><ol class="section"><li><a href="../peripherals/a-first-attempt.html"><strong aria-hidden="true">3.1.</strong> A first attempt in Rust</a></li><li><a href="../peripherals/borrowck.html"><strong aria-hidden="true">3.2.</strong> The Borrow Checker</a></li><li><a href="../peripherals/singletons.html"><strong aria-hidden="true">3.3.</strong> Singletons</a></li></ol></li><li><a href="../static-guarantees/index.html"><strong aria-hidden="true">4.</strong> Static Guarantees</a></li><li><ol class="section"><li><a href="../static-guarantees/typestate-programming.html"><strong aria-hidden="true">4.1.</strong> Typestate Programming</a></li><li><a href="../static-guarantees/state-machines.html"><strong aria-hidden="true">4.2.</strong> Peripherals as State Machines</a></li><li><a href="../static-guarantees/design-contracts.html"><strong aria-hidden="true">4.3.</strong> Design Contracts</a></li><li><a href="../static-guarantees/zero-cost-abstractions.html"><strong aria-hidden="true">4.4.</strong> Zero Cost Abstractions</a></li></ol></li><li><a href="../portability/index.html"><strong aria-hidden="true">5.</strong> Portability</a></li><li><a href="../concurrency/index.html"><strong aria-hidden="true">6.</strong> Concurrency</a></li><li><a href="../collections/index.html"><strong aria-hidden="true">7.</strong> Collections</a></li><li><a href="../c-tips/index.html"><strong aria-hidden="true">8.</strong> Tips for embedded C developers</a></li><li><a href="../interoperability/index.html"><strong aria-hidden="true">9.</strong> Interoperability</a></li><li><ol class="section"><li><a href="../interoperability/c-with-rust.html"><strong aria-hidden="true">9.1.</strong> A little C with your Rust</a></li><li><a href="../interoperability/rust-with-c.html"><strong aria-hidden="true">9.2.</strong> A little Rust with your C</a></li></ol></li><li><a href="../unsorted/index.html"><strong aria-hidden="true">10.</strong> Unsorted topics</a></li><li><ol class="section"><li><a href="../unsorted/speed-vs-size.html" class="active"><strong aria-hidden="true">10.1.</strong> Optimizations: The speed size tradeoff</a></li></ol></li></ol>
        </nav>

        <div id="page-wrapper" class="page-wrapper">

            <div class="page">
                
                <div id="menu-bar" class="menu-bar">
                    <div id="menu-bar-sticky-container">
                        <div class="left-buttons">
                            <button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
                                <i class="fa fa-bars"></i>
                            </button>
                            <button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
                                <i class="fa fa-paint-brush"></i>
                            </button>
                            <ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
                                <li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
                                <li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
                                <li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
                                <li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
                                <li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
                            </ul>
                            
                            <button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
                                <i class="fa fa-search"></i>
                            </button>
                            
                        </div>

                        <h1 class="menu-title">The Embedded Rust Book</h1> 

                        <div class="right-buttons">
                            <a href="../print.html" title="Print this book" aria-label="Print this book">
                                <i id="print-button" class="fa fa-print"></i>
                            </a>
                            
                        </div>
                    </div>
                </div>

                
                <div id="search-wrapper" class="hidden">
                    <form id="searchbar-outer" class="searchbar-outer">
                        <input type="search" name="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
                    </form>
                    <div id="searchresults-outer" class="searchresults-outer hidden">
                        <div id="searchresults-header" class="searchresults-header"></div>
                        <ul id="searchresults">
                        </ul>
                    </div>
                </div>
                

                <!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
                <script type="text/javascript">
                    document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
                    document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
                    Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
                        link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
                    });
                </script>

                <div id="content" class="content">
                    <main>
                        <a class="header" href="#optimizations-the-speed-size-tradeoff" id="optimizations-the-speed-size-tradeoff"><h1>Optimizations: the speed size tradeoff</h1></a>
<p>Everyone wants their program to be super fast and super small but it's usually
not possible to have both characteristics. This section discusses the
different optimization levels that <code>rustc</code> provides and how they affect the
execution time and binary size of a program.</p>
<a class="header" href="#no-optimizations" id="no-optimizations"><h2>No optimizations</h2></a>
<p>This is the default. When you call <code>cargo build</code> you use the development (AKA
<code>dev</code>) profile. This profile is optimized for debugging so it enables debug
information and does <em>not</em> enable any optimizations, i.e. it uses <code>-C opt-level = 0</code>.</p>
<p>At least for bare metal development, debuginfo is zero cost in the sense that it
won't occupy space in Flash / ROM so we actually recommend that you enable
debuginfo in the release profile -- it is disabled by default. That will let you
use breakpoints when debugging release builds.</p>
<pre><code class="language-toml">[profile.release]
# symbols are nice and they don't increase the size on Flash
debug = true
</code></pre>
<p>No optimizations is great for debugging because stepping through the code feels
like you are executing the program statement by statement, plus you can <code>print</code>
stack variables and function arguments in GDB. When the code is optimized, trying
to print variables results in <code>$0 = &lt;value optimized out&gt;</code> being printed.</p>
<p>The biggest downside of the <code>dev</code> profile is that the resulting binary will be
huge and slow. The size is usually more of a problem because unoptimized
binaries can occupy dozens of KiB of Flash, which your target device may not
have -- the result: your unoptimized binary doesn't fit in your device!</p>
<p>Can we have smaller, debugger friendly binaries? Yes, there's a trick.</p>
<a class="header" href="#optimizing-dependencies" id="optimizing-dependencies"><h3>Optimizing dependencies</h3></a>
<blockquote>
<p><strong>WARNING</strong> This section uses an unstable feature and it was last tested on
2018-09-18. Things may have changed since then!</p>
</blockquote>
<p>On nightly, there's a Cargo feature named <a href="https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#profile-overrides"><code>profile-overrides</code></a> that lets you
override the optimization level of dependencies. You can use that feature to
optimize all dependencies for size while keeping the top crate unoptimized and
debugger friendly.</p>
<p>Here's an example:</p>
<pre><code class="language-toml"># Cargo.toml
cargo-features = [&quot;profile-overrides&quot;] # +

[package]
name = &quot;app&quot;
# ..

[profile.dev.overrides.&quot;*&quot;] # +
opt-level = &quot;z&quot; # +
</code></pre>
<p>Without the override:</p>
<pre><code class="language-console">$ cargo size --bin app -- -A
app  :
section               size        addr
.vector_table         1024   0x8000000
.text                 9060   0x8000400
.rodata               1708   0x8002780
.data                    0  0x20000000
.bss                     4  0x20000000
</code></pre>
<p>With the override:</p>
<pre><code class="language-console">$ cargo size --bin app -- -A
app  :
section               size        addr
.vector_table         1024   0x8000000
.text                 3490   0x8000400
.rodata               1100   0x80011c0
.data                    0  0x20000000
.bss                     4  0x20000000
</code></pre>
<p>That's a 6 KiB reduction in Flash usage without any loss in the debuggability of
the top crate. If you step into a dependency then you'll start seeing those
<code>&lt;value optimized out&gt;</code> messages again but it's usually the case that you want
to debug the top crate and not the dependencies. And if you <em>do</em> need to debug a
dependency then you can use the <code>profile-overrides</code> feature to exclude a
particular dependency from being optimized. See example below:</p>
<pre><code class="language-toml"># ..

# don't optimize the `cortex-m-rt` crate
[profile.dev.overrides.cortex-m-rt] # +
opt-level = 0 # +

# but do optimize all the other dependencies
[profile.dev.overrides.&quot;*&quot;]
codegen-units = 1 # better optimizations
opt-level = &quot;z&quot;
</code></pre>
<p>Now the top crate and <code>cortex-m-rt</code> are debugger friendly!</p>
<a class="header" href="#optimize-for-speed" id="optimize-for-speed"><h2>Optimize for speed</h2></a>
<p>As of 2018-09-18 <code>rustc</code> supports three &quot;optimize for speed&quot; levels: <code>opt-level = 1</code>, <code>2</code> and <code>3</code>. When you run <code>cargo build --release</code> you are using the release
profile which defaults to <code>opt-level = 3</code>.</p>
<p>Both <code>opt-level = 2</code> and <code>3</code> optimize for speed at the expense of binary size,
but level <code>3</code> does more vectorization and inlining than level <code>2</code>. In
particular, you'll see that at <code>opt-level</code> equal to or greater than <code>2</code> LLVM will
unroll loops. Loop unrolling has a rather high cost in terms of Flash / ROM
(e.g. from 26 bytes to 194 for a zero this array loop) but can also halve the
execution time given the right conditions (e.g. number of iterations is big
enough).</p>
<p>Currently there's no way to disable loop unrolling in <code>opt-level = 2</code> and <code>3</code> so
if you can't afford its cost you should optimize your program for size.</p>
<a class="header" href="#optimize-for-size" id="optimize-for-size"><h2>Optimize for size</h2></a>
<p>As of 2018-09-18 <code>rustc</code> supports two &quot;optimize for size&quot; levels: <code>opt-level = &quot;s&quot;</code> and <code>&quot;z&quot;</code>. These names were inherited from clang / LLVM and are not too
descriptive but <code>&quot;z&quot;</code> is meant to give the idea that it produces smaller
binaries than <code>&quot;s&quot;</code>.</p>
<p>If you want your release binaries to be optimized for size then change the
<code>profile.release.opt-level</code> setting in <code>Cargo.toml</code> as shown below.</p>
<pre><code class="language-toml">[profile.release]
# or &quot;z&quot;
opt-level = &quot;s&quot;
</code></pre>
<p>These two optimization levels greatly reduce LLVM's inline threshold, a metric
used to decide whether to inline a function or not. One of Rust principles are
zero cost abstractions; these abstractions tend to use a lot of newtypes and
small functions to hold invariants (e.g. functions that borrow an inner value
like <code>deref</code>, <code>as_ref</code>) so a low inline threshold can make LLVM miss
optimization opportunities (e.g. eliminate dead branches, inline calls to
closures).</p>
<p>When optimizing for size you may want to try increasing the inline threshold to
see if that has any effect on the binary size. The recommended way to change the
inline threshold is to append the <code>-C inline-threshold</code> flag to the other
rustflags in <code>.cargo/config</code>.</p>
<pre><code class="language-toml"># .cargo/config
# this assumes that you are using the cortex-m-quickstart template
[target.'cfg(all(target_arch = &quot;arm&quot;, target_os = &quot;none&quot;))']
rustflags = [
  # ..
  &quot;-C&quot;, &quot;inline-threshold=123&quot;, # +
]
</code></pre>
<p>What value to use? <a href="https://github.com/rust-lang/rust/blob/1.29.0/src/librustc_codegen_llvm/back/write.rs#L2105-L2122">As of 1.29.0 these are the inline thresholds that the
different optimization levels use</a>:</p>
<ul>
<li><code>opt-level = 3</code> uses 275</li>
<li><code>opt-level = 2</code> uses 225</li>
<li><code>opt-level = &quot;s&quot;</code> uses 75</li>
<li><code>opt-level = &quot;z&quot;</code> uses 25</li>
</ul>
<p>You should try <code>225</code> and <code>275</code> when optimizing for size.</p>

                    </main>

                    <nav class="nav-wrapper" aria-label="Page navigation">
                        <!-- Mobile navigation buttons -->
                        
                            <a rel="prev" href="../unsorted/index.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
                                <i class="fa fa-angle-left"></i>
                            </a>
                        

                        

                        <div style="clear: both"></div>
                    </nav>
                </div>
            </div>

            <nav class="nav-wide-wrapper" aria-label="Page navigation">
                
                    <a href="../unsorted/index.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
                        <i class="fa fa-angle-left"></i>
                    </a>
                

                
            </nav>

        </div>

        

        

        

        
        <script src="../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
        <script src="../mark.min.js" type="text/javascript" charset="utf-8"></script>
        <script src="../searcher.js" type="text/javascript" charset="utf-8"></script>
        

        <script src="../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
        <script src="../highlight.js" type="text/javascript" charset="utf-8"></script>
        <script src="../book.js" type="text/javascript" charset="utf-8"></script>

        <!-- Custom JS scripts -->
        

        

    </body>
</html>