mirror of
https://github.com/godotengine/godot-contributing-docs.git
synced 2025-12-31 05:48:13 +03:00
172 lines
7.3 KiB
ReStructuredText
172 lines
7.3 KiB
ReStructuredText
.. _doc_optimization:
|
|
|
|
Optimization guidelines
|
|
=======================
|
|
|
|
Introduction
|
|
------------
|
|
|
|
In general, the project prefers clear, simple code over highly optimized code,
|
|
except in bottlenecks.
|
|
|
|
However, optimization PRs are welcome provided they follow the guidelines below.
|
|
|
|
.. note::
|
|
|
|
The project doesn't automatically accept all optimization PRs, even if they
|
|
improve performance.
|
|
|
|
Choosing what to optimize
|
|
-------------------------
|
|
|
|
Predicting which code would benefit from optimization can be difficult without
|
|
using performance analysis tools.
|
|
|
|
Oftentimes code that looks slow has no impact on overall performance, and code
|
|
that looks like it should be fast has a huge impact on performance. Further,
|
|
reasoning about why a certain chunk of code is slow is often impossible to do
|
|
without detailed metrics (e.g. from a profiler).
|
|
|
|
Instructions on using some common profilers with Godot can be found `here
|
|
<https://docs.godotengine.org/en/stable/engine_details/development/debugging/using_cpp_profilers.html>`_.
|
|
|
|
As an example, you may optimize a chunk of code by caching intermediate values.
|
|
However, if that code was slow due to memory constraints, caching the values and
|
|
reading them later may be even slower than calculating them from scratch!
|
|
|
|
Similarly, if the code is relatively slow but is only called rarely (for
|
|
instance once on level load), then there is less potential benefit to speeding
|
|
it up (unless you are specifically optimizing load times).
|
|
|
|
Most optimizations involve making a tradeoff, so instead of randomly picking a
|
|
part of the engine to optimize, we recommend that you use a profiler to identify
|
|
bottlenecks **before** making any changes to ensure that your optimization will
|
|
make a difference.
|
|
|
|
If an area of the engine is not appearing in a profile, no matter how
|
|
inefficient the code, then a PR is unlikely to be approved and merged.
|
|
|
|
*(There are some exceptions, but this is generally the pattern.)*
|
|
|
|
When in doubt, look for Github issues tagged with the `performance
|
|
<https://github.com/godotengine/godot/issues?q=is%3Aissue%20state%3Aopen%20label%3Aperformance>`_
|
|
label to guide your optimization efforts.
|
|
|
|
When assessing optimization opportunities, we need to take into account:
|
|
|
|
Benefits
|
|
~~~~~~~~
|
|
|
|
Is the optimization worth doing in this case?
|
|
|
|
- How often is this code called?
|
|
- How much of a bottleneck is it to overall performance?
|
|
- Does profiling show it to be a bottleneck?
|
|
|
|
Costs
|
|
~~~~~
|
|
|
|
What are the downsides?
|
|
|
|
- Code complexity
|
|
- Code readability
|
|
- Maintenance burden
|
|
- Constraining future changes
|
|
- Risk of regressions
|
|
|
|
Optimization process
|
|
--------------------
|
|
|
|
Once you have decided what you should optimize, you should start by capturing a
|
|
baseline profile in your profiler of choice. Ensure you are running Godot's
|
|
latest ``master`` branch and that you use an optimized build of Godot, since many
|
|
things that run slowly in debug end up disappearing with optimizations enabled.
|
|
|
|
By default, Godot builds with optimizations enabled. See `the Godot build docs
|
|
<https://docs.godotengine.org/en/stable/engine_details/development/compiling/introduction_to_the_buildsystem.html#optimization-level>`_
|
|
for more information about build optimization settings.
|
|
|
|
In some cases using a synthetic benchmark is also acceptable, but remember that
|
|
Godot is a game engine. The golden standard is to test the performance of real
|
|
games. Benchmarks can be helpful, but they can also be misleading because it is
|
|
very difficult to create benchmarks that reflect how performant the code will be
|
|
in an actual game.
|
|
|
|
Once you have your baseline profile/benchmark, make your changes and rebuild the
|
|
engine with the exact same build settings you used before. Then profile again
|
|
and compare the results.
|
|
|
|
.. note::
|
|
|
|
Results will fluctuate, so you'll need to make your test project or
|
|
benchmark intensive enough to isolate the code you're trying to optimize (ideally,
|
|
go for at least 2 seconds of real-life runtime). Additionally, you should run the
|
|
test multiple times, and observe how much the results fluctuate. Fluctuations of up
|
|
to 10% are common and expected. The fastest run is usually the most accurate number.
|
|
|
|
Pull request requirements
|
|
-------------------------
|
|
|
|
When making an optimization PR you should:
|
|
|
|
- Explain why you chose to optimize this code (e.g. include the profiling result, link the issue report, etc.).
|
|
- Show that you improved the code either by profiling again, or running systematic benchmarks.
|
|
- Test on multiple platforms where appropriate, especially mobile.
|
|
- When micro-optimizing, show assembly before / after where appropriate.
|
|
|
|
In particular, you should be aware that for micro-optimizations, C++ compilers will often
|
|
be aware of basic tricks and will already perform them in optimized builds. This is why
|
|
showing before / after assembly can be important in these cases.
|
|
(`godbolt <https://godbolt.org/>`_ can be particularly useful for this purpose.)
|
|
|
|
The most important point to get across in your PR is to highlight the source of
|
|
the performance issues, and have a clear explanation for how your PR fixes that
|
|
performance issue. Your profiling/benchmarking results are proof that your
|
|
optimization was successful.
|
|
|
|
Optimizing for best / worst cases
|
|
---------------------------------
|
|
|
|
Often in optimization there can be situations where optimizing for a rare case slows a
|
|
common case, or vice versa. Be aware that surprisingly often in games, optimizing for
|
|
the worst case can be more important than optimizing for the best case, as worst cases
|
|
can cause dropped frames.
|
|
|
|
In situations where a PR is trading off speed in different paths, reviewers may have to
|
|
decide whether a change is worth making.
|
|
|
|
GPU optimization
|
|
----------------
|
|
|
|
GPU optimization can be even more fraught with difficulty than CPU optimization,
|
|
primarily because of the vast range of hardware the engine must run on, differences in
|
|
drivers and behavior, and aggressive power saving modes that downclock the GPU when
|
|
not under stress.
|
|
|
|
Even more so than for CPU work, it is essential to test GPU changes on mobile as well as
|
|
desktop, and the more platforms, the better.
|
|
|
|
In particular, you should be aware that changes which increase performance on one platform
|
|
can often reduce performance on another.
|
|
|
|
Compilation time optimization
|
|
-----------------------------
|
|
|
|
Optimizing compile time can be a worthwhile goal, because it improves how easy it is to
|
|
work on the Godot codebase, especially for people with older hardware. Godot's compile time
|
|
is `monitored and tested every day <https://benchmarks.godotengine.org/graph/build-time/>`__.
|
|
|
|
Like with all optimization efforts, it is essential to focus on parts of the build system
|
|
that have a large impact on compile time. This is not possible without profiling the
|
|
compiler.
|
|
|
|
SCons, the build system that Godot is using, does not currently support profiling.
|
|
However, it is possible to use `compile_commands.json <https://docs.godotengine.org/en/latest/engine_details/development/configuring_an_ide/index.html#doc-configuring-an-ide>`__
|
|
to isolate a single compile step to profile. In gcc/clang, you can profile using
|
|
the ``-ftime-trace`` argument, while in MSVC, this is accomplished using ``vcperf``'s
|
|
``/timetrace``.
|
|
|
|
In addition, we have a tracker that analyzes all time traces to estimate which headers should be
|
|
investigated to improve overall compile time. You can find this tracker on the Godot repository:
|
|
`[TRACKER] Compile time issues <https://github.com/godotengine/godot/issues/111218>`__.
|