DOTS Best Practices guide (0.50, 0.51)

We’ve published a revised version of DOTS Best Practices. The initial version was based around Entities 0.16/0.17, so the new version brings us up to date, to Entities 0.50/0.51. Because the Unity Learn platform doesn’t let you select different versions of a guide by selecting a package version, the revised edition is shown when you select the Unity version of 2021.3, or by default.

The revised version of the guide covers a number of changes, including:

  • Some more information on DOD fundamentals
  • Updated information on debugging tools
  • Changes in code samples to reflect changes in the API
  • Updated benchmark test results to show newer hardware and changes in performance characteristics in newer version of DOTS, and to hopefully present the information more clearly
  • Tweaked advice about structural changes, as a result of changing performance characteristics.
  • A new section discussing job/system granularity. Unity users have uncovered performance overheads in the job scheduler, in job/system dependency management and in repeated work performed by multiple systems. These issues had not been on my radar when I wrote the first version of the guide. Some of them will be addressed in future versions of Unity and/or the DOTS packages, but the DOTS team and I recognized that these are important issues when working with the current versions of the packages
  • A short new section with some useful resources on Burst Intrinsics
22 Likes

Hi, I catch a few errors:
@1.1 “Beach Ball Simulator: Special Edition - it’s more fun than it looks. Just wait until the player starts moving those green balls around!” - funny joke as it’s a .png :smile:
@2.1 “Breakout Data Design Worksheet” link is broken - a spreadsheet is private
@2.3 " learning resources" link is also private

I will add more if I found something else.

EDIT1
@2.6 “Key Principles” link is also private

I’m glad you found the caption funny, but I’m not sure what the error is? It’s meant to be just an image, not a link to a playable game or anything.

Oops. I’ll get this fixed. There’s a PDF version of the breakout worksheet linked at the top of the page, under the “Materials” heading, which I think should also be linked from the text rather than the original source spreadsheet.

Sorry maybe it’s my English but it sounded like an invitation to watch short animation.

Thanks for the feedback, Krajca. The breakout worksheet link should be fixed to point to the PDF version now. From your other feedback we spotted a bunch of links that ran into problems during the upload/publishing process which are getting fixed as we speak. These links should basically just point to other sections of of the guide, so in the meantime it shouldn’t be too hard to figure out what information the links are trying to direct you to.

I’m sorry you got confused about Beach Ball Simulator - I tried to make it clear that it was an imaginary game that doesn’t really exist, but I can see how you might think that’s not a static image. I will think about how to present that better, probably in the next revision of the guide.

2 Likes

It made sense after reading the guide further :smile:

It’s a great guide. Especially the optimization example at the end. Such specific informations are in scarce in external sources and mostly in C++. Thank you for your work!

1 Like

Thank you, man! For me, it was really useful. A lot of gaps were closed and now I have more connected knowledge of how it works under the hood

1 Like

If I may add, on the section of “Know your memory allocators” it is recommended to use the [DeallocateOnJobCompletion] attribute on “pass[ed] Native containers to the job”.

I believe this is misleading. Specifically, this tag does not function for collections other than the basic NativeArray and nothing in the package Collections supports use of it.

NativeLists, NativeHashMap, and so on must be disposed off using the .Dispose() method following a job. For cases where disposal must be done following completion of a job without manual checks, a disposal job for the corresponding native collection can be done with .Dispose(UsingJobDependency). Using the attribute (or the extension in the ForEach lambda) will result in a invalid operation exception.

Furthermore, IIRC several years back when this attribute was first introduced, it was determined that making it function for other containers was too much of a hassle and made debugging difficult since no explicit deposal method was called in the job scheduling code. I cant find the specific forum post from a unity employee (and this was back in the 0.15ish era so long time ago), but the use of the tag was not recommended and should be replaced by the Dispose methods with job dependency parameters.

Is this no longer the case? Is this tag planned to be expanded to other types of collections? Will the disposal method of native containers be de prioritized to this tag when deciding how to dispose unneeded collections?

2 Likes

I personally would like DeallocateOnJobCompletion to be removed as it is not universally supported all it does is add confusion and obfuscation. It’s a relic from the days of long past.

4 Likes

In section 3.2.4 it is stated

“The graph above clearly shows that using an EntityCommandBuffer to make structural changes is slower than using EntityManager directly, especially when you’re working with an EntityQuery.”

Which in this graph it does, but in the downloadable “Materials Performance_Table_Example.png” the values of EntityManager and ECB are very similar.

I guess its not the same test case, or one of the two is outdated?

Find a bug, tutorial Part 2 No7. the link of “FixedString32” and “FixedString64” cannot work

Thanks folks (and apologies for the delayed response, I was on holiday). I’ve submitted an updated version of the guide which should hopefully go up at some point soon. The revisions are:

  • Remove recommendation to use [DeallocateOnJobCompletion], and instead recommend Dispose() with a JobHandle and point out the problems with the attribute.

  • Remove the link to Performance_Table_Example.png in newer versions of the guide - it shows performance information from older versions of the DOTS packages and guide.

  • Changed the text and links about FixedStrings. I hadn’t spotted that they have been renamed to FixedString32Bytes, FixedString64Bytes, etc.

9 Likes

Part 3.4

I think it is in this chapter that you should propose 2 short examples for EntityManager and NativeArray.

Also, it would be nice to mark a clear division between this one and the previous one about “Settings Flags”.

I mainly use Flags in my Entities.ForEach(), which is the fastest solution (for the moment if I’m not mistaken).
.
However, as that previous chapter ends with “This approach has some downsides”, one would be tempted to think that better solutions will be explained. When in fact it talks about Structural changes.

I had to reread this part several times to clear up my doubts.

I hope what I am trying to say makes sense.
Otherwise, this course is a must. I need the same for Burst.

Although there aren’t code samples here, I hoped that the table above contained adequate descriptions of the approach:

EntityQuery (EQ): An EntityQuery is passed to the AddComponent() call to specify which entities should have the component added to them

NativeArray (Array): A NativeArray is passed to the AddComponent() call to specify which entities should have the component added to them

The structural changes section was the hardest to write in the first revision, and was the hardest part to rewrite for this revision. I expect it will see another major rewrite in the next revision as well.

Real talk: structural changes have turned out to be a bigger and more complex problem from a performance standpoint than we anticipated when the first versions of ECS were conceived. Many of these problems only became apparent when we started seeing DOTS in use in full-scale production code (as opposed to the “10,000 spinning cubes” type scenarios which are often used to test, verify and demonstrate behaviour as the API is being written). Seeing these issues “in the wild” was a big part of the motivation for me writing the guide in the first place, and the benchmark tests I wrote for this part of the guide have now been adapted as part of our internal testing framework to check for performance regressions between versions. The Entities team are still actively working on improvements in this area, which means that the performance characteristics and APIs around structural changes are still changing from version to version. For Entities 0.50/0.51 and for future versions until things settle down, I’ll have to re-run these tests, arrive at new conclusions about the performance characteristics, and make the best recommendations I can.

Often, these recommendations are written with very careful language (“Prefer”, “Consider”, “Understand”, “Investigate”) because the best approach is very situation-specific. Always, I have to consult with the Entities team to ensure I don’t make recommendations that will land people in trouble when newer versions land, even though I can’t make specific concrete promises/predictions about what will change in the future, or when. This version of the guide is in a particularly strange position, where mainly all I can do is point out the performance and the potential problems with each approach and try to persuade people not to do anything which will make their lives harder in the future.

It is my hope (and from what I’ve seen, my strong belief) that future versions of the guide will be able to make this section shorter, and with clearer advice. I’m looking forward to that :slight_smile:

6 Likes

Thank you for this clarification.

It’s clear that restructuring all this information is a huge job. After all, it is learning a new paradigm coupled with a new framework using a new compiler.
I must admit that, as far as I’m concerned, I need examples as much as written explanations. Videos are not really my cup of tea so this guide is invaluable.

Also, it’s not a big deal, but could you or someone point out to the team working on Unity Learn that the site is not responsive (cf. image). The code in the code boxes is truncated, it’s not ideal on desktop.

Thanks again.

1 Like

I know the Learn team are working on new formatting for the best practice guide content that’s on there. I’ll pass this feedback on, because - yeah, it’s not a great use of screen space.

3 Likes

This was very helpful for me! I’ve got a much clearer idea of how to proceed with the ECS now.

(also, i appreciated being able to read everything!)

1 Like

Has anyone been able to get a .51.1 build to work on the Quest 2. I can’t get a build to work even though it works in editor and on Rift S

Does this guide also apply to new experimental 1.0 release?

Many will.
But there are breaking changes in various areas, which affects how things work.

I.e. with ISystem you will be able to burst system, or entity manager.
Transforms changes.
Entities.foreach stays for now, but is going to be replaced.
Adding /removing components tags, don’t imply structural changes. (Edit: I mean enable/disable components tags don’t need structural changes).
Some IJobs changes boiler plate. Plus there is coming mask.
Etc.

1 Like