From 4390f7449d9d7bfd65d05235566065c5599384ca Mon Sep 17 00:00:00 2001 From: Mike Date: Thu, 26 Oct 2023 19:22:29 -0700 Subject: [PATCH] 0.12: Tracing Span Caching (#774) Co-authored-by: Carter Anderson Co-authored-by: Pascal Hertleif --- content/news/2023-10-21-bevy-0.12/index.md | 10 ++++++++++ .../tracing-overhead-reduction.png | Bin 0 -> 15119 bytes 2 files changed, 10 insertions(+) create mode 100644 content/news/2023-10-21-bevy-0.12/tracing-overhead-reduction.png diff --git a/content/news/2023-10-21-bevy-0.12/index.md b/content/news/2023-10-21-bevy-0.12/index.md index 332dd2c821..202ef579d3 100644 --- a/content/news/2023-10-21-bevy-0.12/index.md +++ b/content/news/2023-10-21-bevy-0.12/index.md @@ -356,12 +356,22 @@ Try the new `time` example to get a better feel for these resources. The fix for the windup problem was limiting how much `Time` can advance from a single frame. This then limits how many times `FixedUpdate` can be queued for the next frame, and so things like frame lag or your computer waking up from a long sleep can no longer cause a death spiral. So now, the app won't freeze, but things happening in `FixedUpdate` will appear to slow down since it'll be running at a temporarily reduced rate. + +## Reduced Tracing Overhead + +
authors: @hymm, @james7132
+ +Bevy uses the [tracing](https://crates.io/crates/tracing) library to measure system running time (among other things). This is useful for determining where bottlenecks in frame time are and measuring performance improvements. These traces can be visualized using the [tracy](https://github.com/wolfpld/tracy) tool. However, using tracing's spans has a significant overhead to it. A large part of the per-span overhead is due to allocating the string description of the span. By caching the spans for systems, commands, and parallel iteration, we have significantly reduced the CPU time overhead when using tracing. In the PR that introduced system span caching, our "many foxes" stress test went from 5.35 ms to 4.54 ms. In the PR that added caching for the parallel iteration spans, our "many cubes" stress test went from 8.89 ms to 6.8 ms. + +![tracing overhead](tracing-overhead-reduction.png) + ## What's Next? We have plenty of work that is pretty much finished and is therefore very likely to land in **Bevy 0.13**: Check out the [**Bevy 0.13 Milestone**](https://github.com/bevyengine/bevy/milestone/17) for an up-to-date list of current work being considered for **Bevy 0.13**. + ## Support Bevy Sponsorships help make our work on Bevy sustainable. If you believe in Bevy's mission, consider [sponsoring us](/community/donate) ... every bit helps! diff --git a/content/news/2023-10-21-bevy-0.12/tracing-overhead-reduction.png b/content/news/2023-10-21-bevy-0.12/tracing-overhead-reduction.png new file mode 100644 index 0000000000000000000000000000000000000000..8c8210885d8d90d796c96e6347d37c01e7d638e9 GIT binary patch literal 15119 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 iq^Mnh4NPhQun!7ax2%yl!!8Xi zJ{LFZQ`Mgzv^VfifiJeUrntEKhi+5c2=tp9Mo@`a6K;RA^YADbm^=aPhF$4K8@@&- zC)Xy~;1Qsh=;)_71W&kd7PKsa@x%nd_U??h9?Nase5tn#_wKcG?OKfLMDV9>6`zf+$N+OD=^JF3F}MA!#m%XyMp(34P#vdV{cjEX>?iMJqi7XC&<;9k zMNaNmhJOcFyv*!aNta_ngbH}SEoo&3RJv-!5WTR4S%n*QJd(Q@4!e=6d3J+JcnXB~8` z)X?UxLP}|)^SZT!JKBz5OB$3>nL#zOGIBtyzLuS?EnJD?xm7k6s{s2&=z2gMx1&rr*%3)CGTfJCOzO$yrmo`BT4ua{ zJ@bTvGFQlU+~Mqa${wWrtxox5q^P$auKjLZNr3NfoQ)ctCBAwS;HT_WwSPIP!H(-T zXqqPMl3FNdwLffcR|0JvOLD9ObFQnyK)RTmR$5QN6zj86qH2qQxZu01J?}9BZNqVa zHVT;4tBQGLL@N^0=h=FjikKRB0@3Aotjdf{q|9WgQ#qC4&U)pW&Zs}fSC+4E^J*d~ z&l@a@JHY1rxP4A;*q86J;A8W2OAYw_^9l;4Y6^@gCxcMQ%cDy$6XhC@( zN9}8u-k=CKLGYB%);v7Gw~SY79zPdsD7orW9%h^TK-=ULSqwlN`}mMOa^(1R(7y-x zc$hrT8$m0nEwb3J7QF=?q3kyT-s=gsw4E3dRAzP%8kc(wb2y3hAW2l_7Q