diff --git a/_static/redirects.csv b/_static/redirects.csv index 664ab8ce08b..363fc1bd867 100644 --- a/_static/redirects.csv +++ b/_static/redirects.csv @@ -482,3 +482,6 @@ source,destination /contributing/development/editor/index.html,/engine_details/editor/index.html /contributing/development/editor/introduction_to_editor_development.html,/engine_details/editor/introduction_to_editor_development.html /contributing/development/file_formats/gdscript_grammar.html,/engine_details/file_formats/gdscript_grammar.html +/engine_details/development/debugging/using_cpp_profilers.html,/engine_details/development/profiling/index.html +/engine_details/development/debugging/profiling/sampling_profilers.html,/engine_details/development/profiling/index.html +/engine_details/development/debugging/profiling/tracing_profilers.html,/engine_details/development/profiling/index.html diff --git a/engine_details/development/debugging/index.rst b/engine_details/development/debugging/index.rst index 4a5e82fe541..509de6b8ddf 100644 --- a/engine_details/development/debugging/index.rst +++ b/engine_details/development/debugging/index.rst @@ -1,7 +1,7 @@ :allow_comments: False -Debugging and profiling -======================= +Debugging +========= This section contains pages that provide guidance if you're looking at the engine code trying to find an underlying issue or an optimization possibility. @@ -10,7 +10,6 @@ engine code trying to find an underlying issue or an optimization possibility. :maxdepth: 1 :name: toc-devel-cpp-debug-profiling - using_cpp_profilers using_sanitizers macos_debug vulkan/index diff --git a/engine_details/development/debugging/profiling/sampling_profilers.rst b/engine_details/development/debugging/profiling/sampling_profilers.rst deleted file mode 100644 index d1c4d88e002..00000000000 --- a/engine_details/development/debugging/profiling/sampling_profilers.rst +++ /dev/null @@ -1,152 +0,0 @@ -.. _doc_sampling_profilers: - -Sampling profilers -================== - -Recommended profilers ---------------------- - -- `VerySleepy `__ (Windows only) -- `HotSpot `__ (Linux only) -- `Xcode Instruments `__ (macOS only) - -These profilers may not be the most powerful or flexible options, but their -standalone operation and limited feature set tends to make them easier to use. - -Setting up Godot ----------------- - -To get useful profiling information, it is **absolutely required** to use a Godot -build that includes debugging symbols. Official binaries do not include debugging -symbols, since these would make the download size significantly larger. - -To get profiling data that best matches the production environment (but with debugging symbols), -you should compile binaries with the ``production=yes debug_symbols=yes`` SCons options. - -It is possible to run a profiler on less optimized builds (e.g. ``target=template_debug`` without LTO), -but results will naturally be less representative of real world conditions. - -.. warning:: - - Do *not* strip debugging symbols on the binaries using the ``strip`` command - after compiling the binaries. Otherwise, you will no longer get useful - profiling information when running a profiler. - -Benchmarking startup/shutdown times ------------------------------------ - -If you're looking into optimizing Godot's startup/shutdown performance, -you can tell the profiler to use the ``--quit`` command line option on the Godot binary. -This will exit Godot just after it's done starting. -The ``--quit`` option works with ``--editor``, ``--project-manager``, and -``--path `` (which runs a project directly). - -.. seealso:: - - See :ref:`doc_command_line_tutorial` for more command line arguments - supported by Godot. - -Profiler-specific instructions ------------------------------- - -VerySleepy -~~~~~~~~~~ - -- Start the Godot editor or your project first. - If you start the Project Manager, make sure to edit or run a project first. - Otherwise, the profiler will not track the child process since the Project Manager - will spawn a child process for every project edited or run. -- Open VerySleepy and select the Godot executable in the list of processes on the left: - -.. image:: img/cpp_profiler_verysleepy_select_process.png - -- Click the **Profile All** button on the right to start profiling. -- Perform the actions you wish to profile in the editor or project. When you're done, click **Stop** (*not* Abort). -- Wait for the results window to appear. -- Once the results window appears, filter the view to remove external modules (such as the graphics driver). - You can filter by module by finding a line whose **Module** matches the Godot - executable name, right-clicking that line then choosing - **Filter Module to ** in the dropdown that appears. -- Your results window should now look something like this: - -.. image:: img/cpp_profiler_verysleepy_results_filtered.png - -HotSpot -~~~~~~~ - -- Open HotSpot. Click **Record Data**: - -.. image:: img/cpp_profiler_hotspot_welcome.png - -- In the next window, specify the path to the Godot binary that includes debug symbols. -- Specify command line arguments to run a specific project, with or without the editor. -- The path to the working directory can be anything if an absolute path is used - for the ``--path`` command line argument. Otherwise, it must be set so that - the relative path to the project is valid. -- Make sure **Elevate Privileges** is checked if you have administrative privileges. - While not essential for profiling Godot, this will ensure all events can be captured. - Otherwise, some events may be missing from the capture. - Your settings should now look something like this: - -.. image:: img/cpp_profiler_hotspot_record.png - -- Click **Start Recording** and perform the actions you wish to profile in the editor/project. -- Quit the editor/project normally or use the **Stop Profiling** button in HotSpot - to stop profiling early. Stopping profiling early can result in cleaner profiles - if you're not interested in the engine's shutdown procedure. -- Click **View Results** and wait for the profiling visualization to be generated: - -.. image:: img/cpp_profiler_hotspot_view_results.png - -- Use the tabs at the top to navigate between the different views. These views - show the same data, but in different ways. The **Flame Graph** tab is a good - way to see which functions take up the most time at a glance. These functions - are therefore the most important ones to optimize, since optimizing them will - improve performance the most. -- At the bottom of all tabs except **Summary**, you will also see a list of CPU threads - started by the engine along with the CPU utilization for each thread. - This lets you see threads that can be a bottleneck at a given point in time. - -.. image:: img/cpp_profiler_hotspot_flame_graph.png - -.. note:: - - If you don't want the startup procedure to be included in the profile, you - can also attach HotSpot to a running process by clicking **Record Data** - then setting the **Launch Application** dropdown option to **Attach To - Process(es)**. - - This process attachment-based workflow is similar to the one used by VerySleepy. - -Xcode Instruments -~~~~~~~~~~~~~~~~~ - -- Open Xcode. Select **Open Developer Tool** - **Instruments** from the **Xcode** app menu: -- Double-click on **Time Profiler** in the **Instruments** window: - -.. image:: img/cpp_profiler_xcode_menu.png - -- In the Time Profiler window, click on the **Target** menu, select **Choose target...** - and specify the path to the Godot binary, command line arguments, and environment variables - in the next window. - -.. image:: img/cpp_profiler_time_profiler.png - -- You can also attach the Time Profiler to a running process by selecting it from the **Target** - menu. - -- Click the **Start an immediate mode recording** button to start profiling. - -.. image:: img/cpp_profiler_time_profiler_record.png - -- Perform the actions you wish to profile in the editor or project. When you're done, - click the **Stop** button. - -- Wait for the results to appear. -- At the bottom of the window you will see a call tree for all CPU threads started, and - the **Heaviest Stack Trace** overview. -- Select **Hide system libraries** in the **Call Tree** menu (at the bottom of the window) to - remove external modules. -- You can use the timeline at the top of the window to display details for the specific time period. - -.. image:: img/cpp_profiler_time_profiler_result.png diff --git a/engine_details/development/debugging/profiling/tracing_profilers.rst b/engine_details/development/debugging/profiling/tracing_profilers.rst deleted file mode 100644 index 4b2c4fb24ef..00000000000 --- a/engine_details/development/debugging/profiling/tracing_profilers.rst +++ /dev/null @@ -1,235 +0,0 @@ -.. _doc_tracing_profilers: - -Tracing Profilers -================= - -Godot currently supports two tracing profilers: -`Tracy `__ and `Perfetto `__. - -In order to use either of them, you'll need to build the engine from source. -If you've never done this before, please read -:ref:`these docs ` for the platform you want to profile on. -You'll need to perform the same steps here, but with some additional arguments -for ``scons``. - -.. _doc_tracy_profiler: - -Tracy for Windows, Linux, and macOS ------------------------------------ - -Tracy is an Open Source profiler that runs on a wide variety of platforms, -including Windows, Linux, and macOS. While it is primarily a tracing profiler, -it can also periodically sample data like a -:ref:`sampling profiler `, giving some of the benefits -of both approaches. - -Build Godot with Tracy support -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -First, clone the latest version of the Tracy source code ("0.13.0" at the -time of writing) using Git: - -.. code-block:: shell - - git clone -b v0.13.0 --single-branch https://github.com/wolfpld/tracy.git - -This will create a ``tracy`` directory - you can place this anywhere. - -Next, build the release templates for your platform using ``scons``, but adding -the ``profiler=tracy profiler_path=path/to/tracy`` arguments with the real path -to the ``tracy`` directory, as well as ``debug_symbols=yes`` to allow Tracy's -sampling features to work. - -.. note:: - - You don't have to build release templates, you could also build debug - templates, or even the editor. However, it's generally recommended to - profile release templates, because that is the version your players will - use, and it will perform differently than other types of builds. - -For example, to build release templates for Windows: - -.. code-block:: shell - - scons platform=windows target=template_release debug_symbols=yes profiler=tracy profiler_path=path/to/tracy - -Get the Tracy "server" -~~~~~~~~~~~~~~~~~~~~~~ - -In Tracy terminology, the application you are profiling is the "client", and -the one receiving the data is the "server". - -If you are on Windows, you can download a pre-built ``tracy-profiler.exe`` -from the Tracy `releases page `_. - -However, if you're on Linux or macOS, you'll either need to find a pre-built -binary from a package manager (like ``brew`` or ``nix``), or build it from -source yourself. - -.. note:: - - If you do use a pre-built binary, be sure to use the same version that - you used when building Godot. - -Build the Tracy server from source -++++++++++++++++++++++++++++++++++ - -In order to build Tracy, you'll need to install ``cmake``, which can be -downloaded from the `CMake website `_, or -possibly installed via a package manager (like ``brew`` or ``nix``). - -The full instructions for building Tracy from source can be found in the -`Tracy manual `_, -but here is the TL;DR: - -.. code-block:: shell - - # On Linux, Tracy uses Wayland by default, so if you use X11 add -DLEGACY=1 - cmake -B profiler/build -S profiler -DCMAKE_BUILD_TYPE=Release - cmake --build profiler/build --config Release --parallel - -This will place the binary at ``tracy/profiler/build/tracy-profiler`` or -``tracy/profiler/build/tracy-profiler.exe`` (on Windows). - -Record a trace -~~~~~~~~~~~~~~ - -Launch the Tracy server - you'll see something like this: - -.. image:: img/cpp_profiler_tracy_start.webp - -Press "connect". This will ensure tracy makes a connection immediately when -the game launches. If you forget to press "connect", Tracy will store system -events in RAM, which can quickly blow up your memory usage (see the -``TRACY_ON_DEMAND`` documentation). - -Now, export your game using the release templates you built above, and run it. -As soon as both are running, and you have pressed the "Connect" button in -Tracy, you'll see data coming in: - -.. image:: img/cpp_profiler_tracy_recording.webp - -When you think you've gathered enough data, press the "Stop" button. If you -clicked somewhere and the box with the "Stop" button disappeared, you can -click the top-left most icon to bring it back. - -Examining the trace -~~~~~~~~~~~~~~~~~~~ - -Here are some of the basic controls: - -- Zoom in/out with the mouse wheel -- Right click and drag to move forward/backward on the timeline -- In the top bar, click the left and right arrow buttons by "Frames" to move a single frame on the timeline - -To learn more, see the -`Tracy manual `_. - -Perfetto for Android --------------------- - -Perfetto is the default tracing system for Android. In fact, its system tracing -service has been built into the platform since Android 9. - -Build Godot with Perfetto support -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -First, clone the latest version of the Perfetto source code ("53.0" at the -time of writing) using Git: - -.. code-block:: shell - - git clone -b v53.0 --single-branch https://github.com/google/perfetto.git - -This will create a ``perfetto`` directory - you can place this anywhere. - -Next, build the Android debug or release templates for your architecture using -``scons`` (per :ref:`Compiling for Android `), but -adding the ``profiler=perfetto profiler_path=path/to/perfetto`` arguments with -the real path to the ``perfetto`` directory. - -.. note:: - - It's generally recommended to profile release templates, because that is - the version your players will use, and it will perform differently than - other types of builds. However, in the case of Android, it can sometimes - be useful to use debug templates, because Godot can only do remote - debugging of games exported from debug templates. - -For example, to build the release templates for arm64: - -.. code-block:: shell - - scons platform=android target=template_release arch=arm64 generate_android_binaries=yes profiler=perfetto profiler_path=path/to/perfetto - -Configuration -~~~~~~~~~~~~~ - -Perfetto requires a configuration file to tell it which events to track. - -Create a file called ``godot.config`` inside of the ``perfetto`` directory -with this content: - -.. code-block:: text - - # Trace for 10 seconds. - duration_ms: 10000 - - buffers { - size_kb: 32768 - fill_policy: RING_BUFFER - } - - # Write to file once every second to prevent overflowing the buffer. - write_into_file: true - file_write_period_ms: 1000 - - # Track events in the "godot" category. - data_sources { - config { - name: "track_event" - track_event_config { - enabled_categories: "godot" - } - } - } - -Record a trace -~~~~~~~~~~~~~~ - -Finally, launch your game on an Android device using the export templates you -built earlier. - -When you're ready to record a trace (for example, when you've hit the part of -your game that is exhibiting performance issues), you can use this script that -comes with the Perfetto source code: - -.. code-block:: shell - - cd perfetto - ./tools/record_android_trace -c godot.config - -This will record for 10 seconds (per the configuration), or until you press -:kbd:`Ctrl + C`. - -Examining the trace -~~~~~~~~~~~~~~~~~~~ - -As soon as that script exits, it will launch the Perfetto UI in a web browser. - -To see the Godot events, expand the row for your application by clicking on its -Android "Unique Name" (Perfetto will also include some events from system -services in the trace). - -.. image:: img/cpp_profiler_perfetto.webp - -Then you can use the ``WASD`` keys to navigate the graph: - -- Press :kbd:`A` or :kbd:`D` to navigate forward or backward along the timeline -- Press :kbd:`W` or :kbd:`S` to zoom in or out - -You'll probably need to zoom a bit before you're able to see the individual -events from Godot. - -To learn more, see the -`Perfetto UI documentation `_. diff --git a/engine_details/development/debugging/using_cpp_profilers.rst b/engine_details/development/debugging/using_cpp_profilers.rst deleted file mode 100644 index 6c87784fd19..00000000000 --- a/engine_details/development/debugging/using_cpp_profilers.rst +++ /dev/null @@ -1,39 +0,0 @@ -.. _doc_using_cpp_profilers: - -Using C++ profilers -=================== - -To optimize Godot's performance, you need to know what to optimize first. -To this end, profilers are useful tools. - -.. note:: - - There is a :ref:`built-in GDScript profiler ` in the editor, - but using C++ profiler may be useful in cases where the GDScript profiler - is not accurate enough or is missing information due to bugs in the profiler. - -There are two main types of profilers: sampling profilers and tracing profilers. - -Sampling profilers periodically interrupt the running program and take a "sample", -which records which functions are running. Using this information, the profiler -estimates which functions the program spent the most time in. - -Tracing profilers work by recording application-specific events (such as the -start and end of a single frame), producing a log called a "trace". The profiler -can use the trace to produce a graph showing an accurate high-level timeline of -what happened. However, any code that is not explicitly instrumented will not -appear in a tracing profiler's timeline! - -Godot supports both sampling profilers and tracing profilers, and already -includes the logging code for common Godot events for use with a tracing profiler! - -Different problems may be easier to debug with one kind of profiler over the other, -but it's difficult to provide a set of rules for which to use. Give both a try, -and see what you can learn from them! - -.. toctree:: - :maxdepth: 1 - :name: toc-devel-using-cpp-profilers - - profiling/sampling_profilers - profiling/tracing_profilers diff --git a/engine_details/development/index.rst b/engine_details/development/index.rst index 3acfc62eed6..b6fd7619d85 100644 --- a/engine_details/development/index.rst +++ b/engine_details/development/index.rst @@ -16,4 +16,5 @@ If you plan to contribute to the engine, please make sure to also read the configuring_an_ide/index compiling/index debugging/index + profiling/index handling_compatibility_breakages diff --git a/engine_details/development/profiling/hotspot.rst b/engine_details/development/profiling/hotspot.rst new file mode 100644 index 00000000000..9fadabadc30 --- /dev/null +++ b/engine_details/development/profiling/hotspot.rst @@ -0,0 +1,50 @@ +.. _doc_profiler_hotspot: + +Hotspot +======= + +.. seealso:: Please see the :ref:`sampling profiler instructions ` for more information. + +- Open `Hotspot `__. Click **Record Data**: + +.. image:: img/cpp_profiler_hotspot_welcome.png + +- In the next window, specify the path to the Godot binary that includes debug symbols. +- Specify command line arguments to run a specific project, with or without the editor. +- The path to the working directory can be anything if an absolute path is used + for the ``--path`` command line argument. Otherwise, it must be set so that + the relative path to the project is valid. +- Make sure **Elevate Privileges** is checked if you have administrative privileges. + While not essential for profiling Godot, this will ensure all events can be captured. + Otherwise, some events may be missing from the capture. + Your settings should now look something like this: + +.. image:: img/cpp_profiler_hotspot_record.png + +- Click **Start Recording** and perform the actions you wish to profile in the editor/project. +- Quit the editor/project normally or use the **Stop Profiling** button in Hotspot + to stop profiling early. Stopping profiling early can result in cleaner profiles + if you're not interested in the engine's shutdown procedure. +- Click **View Results** and wait for the profiling visualization to be generated: + +.. image:: img/cpp_profiler_hotspot_view_results.png + +- Use the tabs at the top to navigate between the different views. These views + show the same data, but in different ways. The **Flame Graph** tab is a good + way to see which functions take up the most time at a glance. These functions + are therefore the most important ones to optimize, since optimizing them will + improve performance the most. +- At the bottom of all tabs except **Summary**, you will also see a list of CPU threads + started by the engine along with the CPU utilization for each thread. + This lets you see threads that can be a bottleneck at a given point in time. + +.. image:: img/cpp_profiler_hotspot_flame_graph.png + +.. note:: + + If you don't want the startup procedure to be included in the profile, you + can also attach Hotspot to a running process by clicking **Record Data** + then setting the **Launch Application** dropdown option to **Attach To + Process(es)**. + + This process attachment-based workflow is similar to the one used by VerySleepy. diff --git a/engine_details/development/debugging/profiling/img/cpp_profiler_hotspot_flame_graph.png b/engine_details/development/profiling/img/cpp_profiler_hotspot_flame_graph.png similarity index 100% rename from engine_details/development/debugging/profiling/img/cpp_profiler_hotspot_flame_graph.png rename to engine_details/development/profiling/img/cpp_profiler_hotspot_flame_graph.png diff --git a/engine_details/development/debugging/profiling/img/cpp_profiler_hotspot_record.png b/engine_details/development/profiling/img/cpp_profiler_hotspot_record.png similarity index 100% rename from engine_details/development/debugging/profiling/img/cpp_profiler_hotspot_record.png rename to engine_details/development/profiling/img/cpp_profiler_hotspot_record.png diff --git a/engine_details/development/debugging/profiling/img/cpp_profiler_hotspot_view_results.png b/engine_details/development/profiling/img/cpp_profiler_hotspot_view_results.png similarity index 100% rename from engine_details/development/debugging/profiling/img/cpp_profiler_hotspot_view_results.png rename to engine_details/development/profiling/img/cpp_profiler_hotspot_view_results.png diff --git a/engine_details/development/debugging/profiling/img/cpp_profiler_hotspot_welcome.png b/engine_details/development/profiling/img/cpp_profiler_hotspot_welcome.png similarity index 100% rename from engine_details/development/debugging/profiling/img/cpp_profiler_hotspot_welcome.png rename to engine_details/development/profiling/img/cpp_profiler_hotspot_welcome.png diff --git a/engine_details/development/debugging/profiling/img/cpp_profiler_perfetto.webp b/engine_details/development/profiling/img/cpp_profiler_perfetto.webp similarity index 100% rename from engine_details/development/debugging/profiling/img/cpp_profiler_perfetto.webp rename to engine_details/development/profiling/img/cpp_profiler_perfetto.webp diff --git a/engine_details/development/debugging/profiling/img/cpp_profiler_time_profiler.png b/engine_details/development/profiling/img/cpp_profiler_time_profiler.png similarity index 100% rename from engine_details/development/debugging/profiling/img/cpp_profiler_time_profiler.png rename to engine_details/development/profiling/img/cpp_profiler_time_profiler.png diff --git a/engine_details/development/debugging/profiling/img/cpp_profiler_time_profiler_record.png b/engine_details/development/profiling/img/cpp_profiler_time_profiler_record.png similarity index 100% rename from engine_details/development/debugging/profiling/img/cpp_profiler_time_profiler_record.png rename to engine_details/development/profiling/img/cpp_profiler_time_profiler_record.png diff --git a/engine_details/development/debugging/profiling/img/cpp_profiler_time_profiler_result.png b/engine_details/development/profiling/img/cpp_profiler_time_profiler_result.png similarity index 100% rename from engine_details/development/debugging/profiling/img/cpp_profiler_time_profiler_result.png rename to engine_details/development/profiling/img/cpp_profiler_time_profiler_result.png diff --git a/engine_details/development/debugging/profiling/img/cpp_profiler_tracy_recording.webp b/engine_details/development/profiling/img/cpp_profiler_tracy_recording.webp similarity index 100% rename from engine_details/development/debugging/profiling/img/cpp_profiler_tracy_recording.webp rename to engine_details/development/profiling/img/cpp_profiler_tracy_recording.webp diff --git a/engine_details/development/debugging/profiling/img/cpp_profiler_tracy_start.webp b/engine_details/development/profiling/img/cpp_profiler_tracy_start.webp similarity index 100% rename from engine_details/development/debugging/profiling/img/cpp_profiler_tracy_start.webp rename to engine_details/development/profiling/img/cpp_profiler_tracy_start.webp diff --git a/engine_details/development/debugging/profiling/img/cpp_profiler_verysleepy_results_filtered.png b/engine_details/development/profiling/img/cpp_profiler_verysleepy_results_filtered.png similarity index 100% rename from engine_details/development/debugging/profiling/img/cpp_profiler_verysleepy_results_filtered.png rename to engine_details/development/profiling/img/cpp_profiler_verysleepy_results_filtered.png diff --git a/engine_details/development/debugging/profiling/img/cpp_profiler_verysleepy_select_process.png b/engine_details/development/profiling/img/cpp_profiler_verysleepy_select_process.png similarity index 100% rename from engine_details/development/debugging/profiling/img/cpp_profiler_verysleepy_select_process.png rename to engine_details/development/profiling/img/cpp_profiler_verysleepy_select_process.png diff --git a/engine_details/development/debugging/profiling/img/cpp_profiler_xcode_menu.png b/engine_details/development/profiling/img/cpp_profiler_xcode_menu.png similarity index 100% rename from engine_details/development/debugging/profiling/img/cpp_profiler_xcode_menu.png rename to engine_details/development/profiling/img/cpp_profiler_xcode_menu.png diff --git a/engine_details/development/profiling/index.rst b/engine_details/development/profiling/index.rst new file mode 100644 index 00000000000..e1e40f9a659 --- /dev/null +++ b/engine_details/development/profiling/index.rst @@ -0,0 +1,109 @@ +.. _doc_using_cpp_profilers: + +Using C++ profilers +=================== + +To optimize Godot's performance, you need to know what to optimize first. +To this end, profilers are useful tools. + +.. note:: + + There is a :ref:`built-in GDScript profiler ` in the editor, + but using a C++ profiler may be useful in cases where the GDScript profiler + is not accurate enough or is missing information due to bugs in the profiler. + +There are two main types of profilers: sampling profilers and tracing profilers. + +Sampling profilers periodically interrupt the running program and take a "sample", +which records which functions are running. Using this information, the profiler +estimates which functions the program spent the most time in. + +Tracing profilers work by recording application-specific events (such as the +start and end of a single frame), producing a log called a "trace". The profiler +can use the trace to produce a graph showing an accurate high-level timeline of +what happened. However, any code that is not explicitly instrumented will not +appear in a tracing profiler's timeline! + +Godot supports both sampling profilers and tracing profilers, and already +includes the logging code for common Godot events for use with a tracing profiler! + +Different problems may be easier to debug with one kind of profiler over the other, +but it's difficult to provide a set of rules for which to use. Give both a try, +and see what you can learn from them! + +.. _doc_sampling_profilers: + +Sampling profilers +------------------ + +We recommend the following sampling profilers: + +- :ref:`VerySleepy ` (Windows only) +- :ref:`Hotspot ` (Linux only) +- :ref:`Instruments ` (Apple only) + +These profilers may not be the most powerful or flexible options, but their +standalone operation and limited feature set tends to make them easier to use. + +Setting up Godot +~~~~~~~~~~~~~~~~ + +To get useful profiling information, it is **absolutely required** to use a Godot +build that includes debugging symbols. Official binaries do not include debugging +symbols, since these would make the download size significantly larger. + +To get profiling data that best matches the production environment (but with debugging symbols), +you should compile binaries with the ``production=yes debug_symbols=yes`` SCons options. + +It is possible to run a profiler on less optimized builds (e.g. ``target=template_debug`` without LTO), +but results will naturally be less representative of real world conditions. + +.. warning:: + + Do *not* strip debugging symbols on the binaries using the ``strip`` command + after compiling the binaries. Otherwise, you will no longer get useful + profiling information when running a profiler. + +Benchmarking startup/shutdown times +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you're looking into optimizing Godot's startup/shutdown performance, +you can tell the profiler to use the ``--quit`` command line option on the Godot binary. +This will exit Godot just after it's done starting. +The ``--quit`` option works with ``--editor``, ``--project-manager``, and +``--path `` (which runs a project directly). + +.. seealso:: + + See :ref:`doc_command_line_tutorial` for more command line arguments + supported by Godot. + +.. _doc_tracing_profilers: + +Tracing profilers +----------------- + +Godot currently supports three tracing profilers: + +- :ref:`Tracy ` +- :ref:`Perfetto ` +- :ref:`Instruments ` (Apple only) + +In order to use either of them, you'll need to build the engine from source. +If you've never done this before, please read +:ref:`these docs ` for the platform you want to profile on. +You'll need to perform the same steps here, but with some additional arguments +for ``scons``. + +All recommended profilers +------------------------- + +.. toctree:: + :maxdepth: 1 + :name: toc-devel-using-cpp-profilers + + hotspot + instruments + perfetto + tracy + very_sleepy diff --git a/engine_details/development/profiling/instruments.rst b/engine_details/development/profiling/instruments.rst new file mode 100644 index 00000000000..933a13142d6 --- /dev/null +++ b/engine_details/development/profiling/instruments.rst @@ -0,0 +1,39 @@ +.. _doc_profiler_instruments: + +Instruments +=========== + +.. seealso:: Please see the :ref:`sampling profiler instructions ` + and the :ref:`tracing profiler instructions ` for + more information. + +- Open `Xcode `__. + Select **Open Developer Tool** - **Instruments** from the **Xcode** app menu: +- Double-click on **Time Profiler** in the **Instruments** window: + +.. image:: img/cpp_profiler_xcode_menu.png + +- In the Time Profiler window, click on the **Target** menu, select **Choose target...** + and specify the path to the Godot binary, command line arguments, and environment variables + in the next window. + +.. image:: img/cpp_profiler_time_profiler.png + +- You can also attach the Time Profiler to a running process by selecting it from the **Target** + menu. + +- Click the **Start an immediate mode recording** button to start profiling. + +.. image:: img/cpp_profiler_time_profiler_record.png + +- Perform the actions you wish to profile in the editor or project. When you're done, + click the **Stop** button. + +- Wait for the results to appear. +- At the bottom of the window you will see a call tree for all CPU threads started, and + the **Heaviest Stack Trace** overview. +- Select **Hide system libraries** in the **Call Tree** menu (at the bottom of the window) to + remove external modules. +- You can use the timeline at the top of the window to display details for the specific time period. + +.. image:: img/cpp_profiler_time_profiler_result.png diff --git a/engine_details/development/profiling/perfetto.rst b/engine_details/development/profiling/perfetto.rst new file mode 100644 index 00000000000..b5412c6e243 --- /dev/null +++ b/engine_details/development/profiling/perfetto.rst @@ -0,0 +1,112 @@ +.. _doc_profiler_perfetto: + +Perfetto +======== + +.. seealso:: Please see the :ref:`tracing profiler instructions ` for more information. + +`Perfetto `__ is the default tracing system for Android. In fact, its system tracing +service has been built into the platform since Android 9. + +Build Godot with Perfetto support +--------------------------------- + +First, clone the latest version of the Perfetto source code ("53.0" at the +time of writing) using Git: + +.. code-block:: shell + + git clone -b v53.0 --single-branch https://github.com/google/perfetto.git + +This will create a ``perfetto`` directory - you can place this anywhere. + +Next, build the Android debug or release templates for your architecture using +``scons`` (per :ref:`Compiling for Android `), but +adding the ``profiler=perfetto profiler_path=path/to/perfetto`` arguments with +the real path to the ``perfetto`` directory. + +.. note:: + + It's generally recommended to profile release templates, because that is + the version your players will use, and it will perform differently than + other types of builds. However, in the case of Android, it can sometimes + be useful to use debug templates, because Godot can only do remote + debugging of games exported from debug templates. + +For example, to build the release templates for arm64: + +.. code-block:: shell + + scons platform=android target=template_release arch=arm64 generate_android_binaries=yes profiler=perfetto profiler_path=path/to/perfetto + +Configuration +------------- + +Perfetto requires a configuration file to tell it which events to track. + +Create a file called ``godot.config`` inside of the ``perfetto`` directory +with this content: + +.. code-block:: text + + # Trace for 10 seconds. + duration_ms: 10000 + + buffers { + size_kb: 32768 + fill_policy: RING_BUFFER + } + + # Write to file once every second to prevent overflowing the buffer. + write_into_file: true + file_write_period_ms: 1000 + + # Track events in the "godot" category. + data_sources { + config { + name: "track_event" + track_event_config { + enabled_categories: "godot" + } + } + } + +Record a trace +-------------- + +Finally, launch your game on an Android device using the export templates you +built earlier. + +When you're ready to record a trace (for example, when you've hit the part of +your game that is exhibiting performance issues), you can use this script that +comes with the Perfetto source code: + +.. code-block:: shell + + cd perfetto + ./tools/record_android_trace -c godot.config + +This will record for 10 seconds (per the configuration), or until you press +:kbd:`Ctrl + C`. + +Examining the trace +------------------- + +As soon as that script exits, it will launch the Perfetto UI in a web browser. + +To see the Godot events, expand the row for your application by clicking on its +Android "Unique Name" (Perfetto will also include some events from system +services in the trace). + +.. image:: img/cpp_profiler_perfetto.webp + +Then you can use the ``WASD`` keys to navigate the graph: + +- Press :kbd:`A` or :kbd:`D` to navigate forward or backward along the timeline +- Press :kbd:`W` or :kbd:`S` to zoom in or out + +You'll probably need to zoom a bit before you're able to see the individual +events from Godot. + +To learn more, see the +`Perfetto UI documentation `_. diff --git a/engine_details/development/profiling/tracy.rst b/engine_details/development/profiling/tracy.rst new file mode 100644 index 00000000000..2488b83afc0 --- /dev/null +++ b/engine_details/development/profiling/tracy.rst @@ -0,0 +1,114 @@ +.. _doc_profiler_tracy: + +Tracy +===== + +.. seealso:: Please see the :ref:`tracing profiler instructions ` for more information. + +`Tracy `__ is an Open Source profiler that runs on a wide variety of platforms, +including Windows, Linux, and macOS. While it is primarily a tracing profiler, +it can also periodically sample data like a +:ref:`sampling profiler `, giving some of the benefits +of both approaches. + +Build Godot with Tracy support +------------------------------ + +First, clone the latest version of the Tracy source code ("0.13.0" at the +time of writing) using Git: + +.. code-block:: shell + + git clone -b v0.13.0 --single-branch https://github.com/wolfpld/tracy.git + +This will create a ``tracy`` directory - you can place this anywhere. + +Next, build the release templates for your platform using ``scons``, but adding +the ``profiler=tracy profiler_path=path/to/tracy`` arguments with the real path +to the ``tracy`` directory, as well as ``debug_symbols=yes`` to allow Tracy's +sampling features to work. + +.. note:: + + You don't have to build release templates, you could also build debug + templates, or even the editor. However, it's generally recommended to + profile release templates, because that is the version your players will + use, and it will perform differently than other types of builds. + +For example, to build release templates for Windows: + +.. code-block:: shell + + scons platform=windows target=template_release debug_symbols=yes profiler=tracy profiler_path=path/to/tracy + +Get the Tracy "server" +---------------------- + +In Tracy terminology, the application you are profiling is the "client", and +the one receiving the data is the "server". + +If you are on Windows, you can download a pre-built ``tracy-profiler.exe`` +from the Tracy `releases page `_. + +However, if you're on Linux or macOS, you'll either need to find a pre-built +binary from a package manager (like ``brew`` or ``nix``), or build it from +source yourself. + +.. note:: + + If you do use a pre-built binary, be sure to use the same version that + you used when building Godot. + +Build the Tracy server from source +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In order to build Tracy, you'll need to install ``cmake``, which can be +downloaded from the `CMake website `_, or +possibly installed via a package manager (like ``brew`` or ``nix``). + +The full instructions for building Tracy from source can be found in the +`Tracy manual `_, +but here is the TL;DR: + +.. code-block:: shell + + # On Linux, Tracy uses Wayland by default, so if you use X11 add -DLEGACY=1 + cmake -B profiler/build -S profiler -DCMAKE_BUILD_TYPE=Release + cmake --build profiler/build --config Release --parallel + +This will place the binary at ``tracy/profiler/build/tracy-profiler`` or +``tracy/profiler/build/tracy-profiler.exe`` (on Windows). + +Record a trace +-------------- + +Launch the Tracy server - you'll see something like this: + +.. image:: img/cpp_profiler_tracy_start.webp + +Press "connect". This will ensure tracy makes a connection immediately when +the game launches. If you forget to press "connect", Tracy will store system +events in RAM, which can quickly blow up your memory usage (see the +``TRACY_ON_DEMAND`` documentation). + +Now, export your game using the release templates you built above, and run it. +As soon as both are running, and you have pressed the "Connect" button in +Tracy, you'll see data coming in: + +.. image:: img/cpp_profiler_tracy_recording.webp + +When you think you've gathered enough data, press the "Stop" button. If you +clicked somewhere and the box with the "Stop" button disappeared, you can +click the top-left most icon to bring it back. + +Examining the trace +------------------- + +Here are some of the basic controls: + +- Zoom in/out with the mouse wheel +- Right click and drag to move forward/backward on the timeline +- In the top bar, click the left and right arrow buttons by "Frames" to move a single frame on the timeline + +To learn more, see the +`Tracy manual `_. diff --git a/engine_details/development/profiling/very_sleepy.rst b/engine_details/development/profiling/very_sleepy.rst new file mode 100644 index 00000000000..0a01079a524 --- /dev/null +++ b/engine_details/development/profiling/very_sleepy.rst @@ -0,0 +1,26 @@ +.. _doc_profiler_very_sleepy: + +VerySleepy +========== + +.. seealso:: Please see the :ref:`sampling profiler instructions ` for more information. + +- Start the Godot editor or your project first. + If you start the Project Manager, make sure to edit or run a project first. + Otherwise, the profiler will not track the child process since the Project Manager + will spawn a child process for every project edited or run. +- Open `VerySleepy `__ and + select the Godot executable in the list of processes on the left: + +.. image:: img/cpp_profiler_verysleepy_select_process.png + +- Click the **Profile All** button on the right to start profiling. +- Perform the actions you wish to profile in the editor or project. When you're done, click **Stop** (*not* Abort). +- Wait for the results window to appear. +- Once the results window appears, filter the view to remove external modules (such as the graphics driver). + You can filter by module by finding a line whose **Module** matches the Godot + executable name, right-clicking that line then choosing + **Filter Module to ** in the dropdown that appears. +- Your results window should now look something like this: + +.. image:: img/cpp_profiler_verysleepy_results_filtered.png