98 lines
15 KiB
HTML
98 lines
15 KiB
HTML
<html>
|
|
<head>
|
|
<title>White Papers | CPU Performance</title>
|
|
<link rel="stylesheet" href="style/docs.css">
|
|
<link rel="stylesheet" href="style/code_highlight.css">
|
|
<script type="text/javascript" src="scripts/language-selector.js"></script></head>
|
|
<body>
|
|
<div class="docs-body">
|
|
<div class="manual-toc">
|
|
<p>FMOD Engine User Manual 2.03</p>
|
|
<ul>
|
|
<li><a href="welcome.html">Welcome to the FMOD Engine</a></li>
|
|
<li><a href="studio-guide.html">Studio API Guide</a></li>
|
|
<li><a href="core-guide.html">Core API Guide</a></li>
|
|
<li><a href="platforms.html">Platform Details</a></li>
|
|
<li class="manual-current-chapter manual-inactive-chapter"><a href="white-papers.html">White Papers</a><ul class="subchapters"><li><a href="white-papers-getting-started.html">Getting Started</a></li><li><a href="white-papers-3d-reverb.html">3D Reverb</a></li><li><a href="white-papers-3d-sounds.html">3D Sounds</a></li><li><a href="white-papers-asynchronous-io.html">Asynchronous I/O</a></li><li class="manual-current-chapter manual-active-chapter"><a href="white-papers-cpu-performance.html">CPU Performance</a></li><li><a href="white-papers-dsp-architecture.html">DSP Architecture and Usage</a></li><li><a href="white-papers-dsp-plugin-api.html">DSP Plug-in API</a></li><li><a href="white-papers-handle-system.html">Handle System</a></li><li><a href="white-papers-memory-management.html">Memory Management</a></li><li><a href="white-papers-non-blocking-sound-creation.html">Non-blocking Sound Creation</a></li><li><a href="white-papers-spatial-audio.html">Spatial Audio</a></li><li><a href="white-papers-studio-3d-events.html">Studio API 3D Events</a></li><li><a href="white-papers-studio-threads.html">Studio API Threads</a></li><li><a href="white-papers-threads.html">Threads and Thread Safety</a></li><li><a href="white-papers-transitioning-from-fmodex.html">Transitioning from FMOD Ex</a></li><li><a href="white-papers-using-multiple-reverbs.html">Using Multiple Reverbs</a></li><li><a href="white-papers-virtual-voices.html">Virtual Voices</a></li></ul></li>
|
|
<li><a href="studio-api.html">Studio API Reference</a></li>
|
|
<li><a href="core-api.html">Core API Reference</a></li>
|
|
<li><a href="fsbank-api.html">FSBank API Reference</a></li>
|
|
<li><a href="plugin-api.html">Plug-in API Reference</a></li>
|
|
<li><a href="effects-reference.html">Effects Reference</a></li>
|
|
<li><a href="troubleshooting.html">Troubleshooting</a></li>
|
|
<li><a href="glossary.html">Glossary</a></li>
|
|
</ul>
|
|
</div>
|
|
<div class="manual-content api">
|
|
<h1>5. White Papers | CPU Performance</h1>
|
|
<div class="toc">
|
|
<ul>
|
|
<li><a href="#cpu-performance">CPU Performance</a><ul>
|
|
<li><a href="#what-is-the-mixer-and-how-is-it-measured">What is the mixer and how is it measured?</a></li>
|
|
<li><a href="#what-else-can-be-measured">What else can be measured?</a></li>
|
|
<li><a href="#voice-limiting">Voice Limiting</a></li>
|
|
<li><a href="#tips-and-tricks">Tips and Tricks</a><ul>
|
|
<li><a href="#sample-rate">Sample Rate</a></li>
|
|
<li><a href="#dsp-block-size">DSP Block Size</a></li>
|
|
<li><a href="#channel-count">Channel Count</a></li>
|
|
<li><a href="#dsp-choice">DSP Choice</a></li>
|
|
<li><a href="#hardware-decoding">Hardware Decoding</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#wrapping-up">Wrapping Up</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<h2 id="cpu-performance"><a href="#cpu-performance">CPU Performance</a></h2>
|
|
<p>Measuring and tweaking performance is an important part of developing any application, and being able to scale FMOD from low power portable devices to the very latest in next gen consoles is key to our design. This guide should give you a solid understanding of how to configure FMOD to fit within your audio budget, no matter which platforms you're targeting.</p>
|
|
<p>Before we jump into the details, let's first consider how performance is measured in FMOD. The primary metric we use, when discussing how expensive something is, is CPU percentage. We can calculate this by measuring the time spent performing an action and comparing it against a known time window; the most common example of this is <a href="glossary.html#dsp">DSP</a> or mixer performance.</p>
|
|
<h4 id="what-is-the-mixer-and-how-is-it-measured"><a href="#what-is-the-mixer-and-how-is-it-measured">What is the mixer and how is it measured?</a></h4>
|
|
<p>When we talk about mixer performance we are actually talking about the production of audio samples being sent to the output (usually your speakers). At regular intervals, our mixer produces a buffer of samples which represents a fixed amount of time for playback. We call this a DSP block. DSP block size often defaults to 512 samples, which when played back at 48 kHz represents ~10ms of audio.</p>
|
|
<p>With a fixed amount of samples being produced regularly, we can now measure how long it takes to produce those samples and receive a percentage. For example, if it took us 5ms of CPU time to produce 10ms of audio, our mixer performance would be 50%. As the CPU time approaches 10ms we risk not delivering the audio in time which results in an audio discontinuity known as stuttering.</p>
|
|
<h4 id="what-else-can-be-measured"><a href="#what-else-can-be-measured">What else can be measured?</a></h4>
|
|
<p>Another key performance area is update, this operation is called regularly to do runtime housekeeping. Our recommendation is you call update once per render frame which is often 30 or 60 times per second. Using the 30 or 60 FPS (frames per second) known time frame we can now measure CPU time spent performing this action to get percentages.</p>
|
|
<p>Armed with the ability to measure performance we now need to identify the things that cost the bulk of the CPU time. The most commonly quoted contributor is <a class="apilink" href="core-api-channel.html">Channel</a> count, following the logic that playing more <a class="apilink" href="core-api-channel.html">Channel</a>s takes up more CPU time. Following is a list of the main contributors to the cost of sound playback:</p>
|
|
<ul>
|
|
<li>Decoding compressed audio to PCM.</li>
|
|
<li>Resampling the PCM to the appropriate pitch.</li>
|
|
<li>Applying <a href="glossary.html#effect">DSP effects</a> to the <a class="apilink" href="core-api-channel.html">Channel</a>.</li>
|
|
<li>Mixing the audio with other sounds to produce the final output you hear.</li>
|
|
</ul>
|
|
<p>Choosing the correct compression format for the kind of audio you want to play and the platform you want to play it on is a big part of controlling the CPU cost. For recommendations on format choice please consult the performance reference for this platform.</p>
|
|
<h3 id="voice-limiting"><a href="#voice-limiting">Voice Limiting</a></h3>
|
|
<p>Once you've settled on a compression format you need to decide how many <a class="apilink" href="core-api-channel.html">Channel</a>s of that format you want to be audible at the same time. There are three ways you can use to control the number of <a class="apilink" href="core-api-channel.html">Channel</a>s playable:</p>
|
|
<p><a class="apilink" href="core-api-system.html#system_init">System::init</a> (maxChannels, ...) The maximum number of <a class="apilink" href="core-api-channel.html">Channel</a>s playing at once.<br />
|
|
<a class="apilink" href="core-api-system.html#system_setsoftwarechannels">System::setSoftwareChannels</a> (numSoftwareChannels) The maximum number of software mixed <a class="apilink" href="core-api-channel.html">Channel</a>s at any one time.<br />
|
|
<a class="apilink" href="core-api-system.html#fmod_advancedsettings">FMOD_ADVANCEDSETTINGS</a> max???Codec The maximum number of decoders where ??? is the compression format.<br />
|
|
For a deep dive into how the virtual voice system works and ways to further control <a class="apilink" href="core-api-channel.html">Channel</a> count please consult the [Virtual Voice System](white-papers-virtual-voices.html] white paper.</p>
|
|
<p>It's often hard to gauge what are good values to use for the above three settings. In rough terms maxChannels should be high enough that you don't hit the cap under normal circumstances, so 256, 512 or even 1024 are reasonable choices. Selecting the values for numSoftwareChannels and maxCodecs depends on the platform and format used. To help choose these values we have provided some recommendations and benchmarks in the performance reference document for this platform.</p>
|
|
<h3 id="tips-and-tricks"><a href="#tips-and-tricks">Tips and Tricks</a></h3>
|
|
<p>With a correctly configured compression format and appropriate <a class="apilink" href="core-api-channel.html">Channel</a> count you are well on your way to an efficiently configured set up. Next up is a series of tips to consider for your project, not all are applicable but they should be considered to get the best performance from FMOD.</p>
|
|
<h4 id="sample-rate"><a href="#sample-rate">Sample Rate</a></h4>
|
|
<p>There are two sample rates you need to think about when optimizing, the System rate and the source audio rate.</p>
|
|
<p>You can control the System sample rate by using <a class="apilink" href="core-api-system.html#system_setsoftwareformat">System::setSoftwareFormat</a> (sampleRate, ...), which by default is 48 kHz. Reducing this can give some big wins in performance because less data is being produced. This setting is a trade off between performance and quality.</p>
|
|
<p>To control the source audio rate you can resample using your favorite audio editor or use the sample rate settings when compressing using the FSBank tool or the FSBankLib API. All audio is sent to a resampler when it is played at runtime, if the source sample rate and the System rate match then the resampler can be essentially skipped saving CPU time. Be aware that this only happens if there are no pitch / frequency settings applied to the <a class="apilink" href="core-api-channel.html">Channel</a>, so this trick is often good for music.</p>
|
|
<h4 id="dsp-block-size"><a href="#dsp-block-size">DSP Block Size</a></h4>
|
|
<p>As mentioned earlier, this represents a fixed amount of samples that are produced regularly to be sent to the speakers. When producing each block of samples there is a fixed amount of overhead, so making the block size larger reduces the overall CPU cost. You can control this setting with <a class="apilink" href="core-api-system.html#system_setdspbuffersize">System::setDSPBufferSize</a> (blockLength, ...), which often defaults to 512 or 1024 samples depending on the platform.</p>
|
|
<p>The trade off with this setting is CPU against mixer granularity, for more information about the implications of changing this setting please consult the API reference for that function.</p>
|
|
<h4 id="channel-count"><a href="#channel-count">Channel Count</a></h4>
|
|
<p>This section refers to channel count in the context of channels as they exist in audio files.<br />
|
|
Controlling how many channels of audio are being played can have a big impact on performance, consider the simple math that 7.1 surround has four times as much data to process compared with stereo. There are a few different places where channel count can be controlled to improve performance.</p>
|
|
<p>The source <a href="glossary.html#audio-channel">audio channel</a> count should be carefully chosen, often mono sources are best, especially for sound that is positioned in 3D. Reducing the channel count at the source is an easy win and also decreases the decoding time for that sound.</p>
|
|
<p>Setting the System channel count controls how 3D sounds are panned when they are given a position in the world. You set this channel count by specifying a speaker mode that represents a well known speaker configuration such as 7.1 surround or stereo. To do this use <a class="apilink" href="core-api-system.html#system_setsoftwareformat">System::setSoftwareFormat</a> (..., speakerMode, ...), the default matches your output device settings.</p>
|
|
<p>As a more advanced setting you can limit the number of channels produced by a sub-mix or the number of channels entering a particular <a href="glossary.html#dsp-effect">DSP effect</a>. This can be especially useful for limiting the channels into an expensive effect. The API to control this is DSP::setChannelFormat(..., speakerMode), by default this is the output of the previous DSP unit.</p>
|
|
<h4 id="dsp-choice"><a href="#dsp-choice">DSP Choice</a></h4>
|
|
<p>Not all DSPs are created equal. Some are computationally simple and use very little CPU, others can be quite expensive. When deciding to use a particular <a href="glossary.html#effect">effect</a> it is important to profile on the target hardware to fully understand the CPU implications.</p>
|
|
<p>The positioning of an effect in the <a href="glossary.html#dsp-graph">DSP graph</a> can make a big difference on a game's resource cost. Placing an effect on every <a href="core-api-channel.html">channel</a> routed into a <a href="core-api-channelgroup.html">channel group</a> means it can affect each of those channels differently, but costs a lot more CPU time than placing that effect only on the channel group. There are no strict rules for where each effect should be positioned, but to give an example, <a href="effects-reference.html#multiband-equalizer">multiband equalizer DSP effects</a> are cheap enough that they can often be applied to every channel without straining a game's resource budget, and the <a href="effects-reference.html#sfx-reverb">SFX reverb DSP effect</a> is expensive enough that it's more common to add a single instance of it to a channel group so that it's applied to the sub-mix.</p>
|
|
<h4 id="hardware-decoding"><a href="#hardware-decoding">Hardware Decoding</a></h4>
|
|
<p>Some platforms have access to hardware assisted decoders, which offload the processing from the CPU to dedicated decoding hardware. These can be utilized by building banks with the corresponding platform's format, such as AT9, XMA, or Opus.</p>
|
|
<p>When using hardware assisted decoders with <a href="glossary.html#stream">streams</a>, each <a class="apilink" href="core-api-channel.html">Channel</a> reserves a hardware decoder for the lifetime of the Channel. This means that the <a href="white-papers-virtual-voices.html">Virtual Voice System</a> is not able to steal any hardware decoders that are in use. As a result, if all hardware decoders are in use, new streamed Channels cannot play until an existing streamed Channel stops and yields its decoder. Therefore, you should not rely on the Virtual Voice System to cull streamed Channels when using hardware decoders. Treat hardware decoders as you would any other limited resource, only using what you need and freeing Channels when they are no longer required.</p>
|
|
<h3 id="wrapping-up"><a href="#wrapping-up">Wrapping Up</a></h3>
|
|
<p>Hopefully now you have a good understanding of the options available for optimizing your usage of FMOD. If in doubt about your particular set up, please make a post on our forums and start a discussion.</p></div>
|
|
|
|
<p class="manual-footer">FMOD Engine User Manual 2.03.07 (2025-04-02). © 2025 Firelight Technologies Pty Ltd.</p>
|
|
</body>
|
|
</html>
|
|
|
|
</div>
|