Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Data oriented designed game in Unity

Discussion in 'Scripting' started by nporaMep, Aug 25, 2015.

  1. nporaMep

    nporaMep

    Joined:
    Oct 31, 2014
    Posts:
    33
    Did anyone created game in Unity using Data Oriented Design?
    It varies how people describe what is it, but I found a lot of theory here http://www.dataorienteddesign.com/dodmain/node1.html and think in general it is building program in a way that decreases amount of cache misses on CPU.

    I am still learning it, but can't find any information how it is related to Unity except component model which is one of major patterns in DOD.

    Questions I don't know answers yet:
    1) How does DOD approach, specifically SOA, works with C# and especially with Unity's MSIL and IL2CPP builds? Is it possible to create effective structures in managed code or better give up earlier?
    2) How bad is such data structuring for all the visual scripting tools in Unity, like inspector, animator etc.
    3) As I see Unity do not try to follow DOD mostly making all the data belong to Components specifically grouped on concrete Game Object. So there are no arrays of transform.position or transform.rotation[] or anything else. Closest thing in Unity to DOD approach is Mesh with vertices/triangles/uv/tangents etc. Why is it so?
    4) There are a lot of talks that virtual methods in OOP, if and switch cases and subroutines are bad for cache misses, but another argument is that JIT inline a lot of such control flow keywords and it means it doesn't have an overhead.
     
    Last edited: Aug 25, 2015
  2. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Never seen it done before. Some of the other programmers may have some input @lordofduct, @eisenpony?

    At a glance it seems like you are sacrificing a ton of simplicity for performance. It might be worth it on a massive game. But it would be overkill for most games.

    It's not for the faint of heart either, you'll need a solid understanding if code and Unity to tackle this. I personally wouldn't touch it unless all other optimisation paths have been tapped out.
     
  3. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,380
    DOD has become increasingly popular with the influx of mobile devices that use ARM based processors that have small cache and slow memory busses.

    When making desktop or console based games. It honestly doesn't make sense. Either your game is simple enough that the benefits are negligible (an extra 1 frame per second when already running at 80+ fps just isn't worth the headache). OR the game you're making is so complex that the DOD approach becomes a nightmare to deal with.

    So for your questions:

    So first concern is the layout of memory. .Net does allow struct layout using the StructLayoutAttribute:
    https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.structlayoutattribute(v=vs.90).aspx

    Simple data structures like arrays are also packed appropriately.

    Classes will have their data structured together nicely, but you don't really get as much control over the layout.

    Arrays of reference objects are NOT really going to give you that much of a benefit. Creating an array and filling it with instances does not guarantee a contiguous block of memory. The only benefit you'll get out of it is that the pointers will be contiguous.

    So to get the benefits out of it, you'll have to be making data structures out of structs and arrays.

    Horrendous!

    Usually you won't actually have such a data structure shown in the inspector. Rather you'll create a custom facade inspector that displays the data in a more manageable way. OR you'll convert existing data into the compact structure at startup (this is what you'll have to do for things like transform positions).

    Because Unity follows a component based design. Which is very OOP oriented. It's a design that is easy for beginners to understand, and it scales very well. DOD doesn't really have any benefits beyond eeking out that extra little bit of efficiency in places that deal with large groupings of data. So a directed DOD approach is used when necessary.

    Mesh data, texture data, data data data... keyword is data.

    DOD doesn't really show benefits until your cache either shrinks so small that your processor is garbage, or your data size is so large that you can't avoid it. Meshes have thousands of verts, each vert with specific information like normal data and skin information attached to it. Textures have 10's of thousands of pixels.

    things like virtual methods will have a performance hit because they fill up the stack more. As you call functions, the memory needed by that function gets pushed onto the stack, and doesn't come off until its done. So if a function A calls another function B, and that calls another function C, the stack is filled up with the memory needs of A,B, and C. Which means that C has less total memory to work with. If a method is virtual, every override of that method is its own function. So C might actually be C1, C2, C3 and so on, just for that one function. When this happens, and the processor cache is small, more work will have to be done to move the stack data around so that only the needed info is readily available to the processor in its cache.

    This is such a place that slow down may occur.

    But it doesn't make it the boogey man either. These tools make designing large software easier. In that the design would become heinous to write if you intended to avoid all these things.

    You're writing in an extremely HIGH level language. You don't get much higher without going into the more interpreted languages like javascript (not unityscript...).

    And yes, the compiler does try to improve things like switch/case statement into quick jump tables and the sort. But it's not guaranteed to happen, it only does it if it can.






    With all this said.

    Taking a sole DOD approach is insane.

    Just like taking a sole OOP approach is insane.

    We mix and match to our needs. Unity DOES use DOD, in the places where it eeks out large benefits. Mesh data and texture data just makes more sense that way.

    Don't stress over it, and just use it where you need it.

    Are you simulating complex movement of 100's of objects at the same time (like physics???) every frame? OK, create arrays of the structures that represent those objects... mirror your data into them, apply the complex operations on them, and then copy them back to all the transforms that need the data. But even then, don't do it until you've profiled and determined this really is where you're getting a performance hit.

    Sure, you take an overall memory hit, but you decrease cache misses.
     
    Last edited: Aug 26, 2015
  4. eisenpony

    eisenpony

    Joined:
    May 8, 2015
    Posts:
    971
    I was initially drawn to this thread but must admit I quickly shied away. I haven't studied DOD much at all.

    The idea of treating every object as a list and only performing set operations to reduce cyclomatic complexity sounds really interesting but I don't see how that will improve performance without muddying game logic.

    To be honest, I come from the enterprise software field where the primary concern is how quickly can features be introduced and defects fixed for minimum cost. Users don't mind waiting a few extra "frames" so long as the results are correct. This performance talk is interesting but primarily of concern for development teams trying to bleed their devices for every ounce of performance. In that light I think you'd also want to offload your algorithms to compute shaders, in which case you're really muddying the water.

    My concern has always been less "what can I do for my computer?" and more "what can my computer do for me?" Frameworks like unity come out of a need to improve programmer performance rather than computer performance.

    Rants aside, I think lordofduct is right on the money when he says
     
  5. nporaMep

    nporaMep

    Joined:
    Oct 31, 2014
    Posts:
    33
    Wow, thank you lordofduct. Such an awesome answer :)

    I was leaning to somewhat same conclusion the longer I read that DOD book.
    It seems it fits if you either build top notch FPS with 10m$ budget and have separate programmer assigned to few number of subfeatures for several years or if you build very complex MMO or RTS. Those should probably have its own engines.
    For game up to Hearthstone complexity Unity is super fine in how it is built now, and DOD may be applied partially in pre-release for performance reasons.
    Even so I saw HonorBuddy (WoW bot program) C# interface to WoW process memory and it seems they also have classes for Player/Mobs/Location and those have tons of fields. May be it is so on client side only, or HonorBuddy developers created those classes, or WoW scale works without DOD
     
  6. BluePyro

    BluePyro

    Joined:
    Aug 15, 2021
    Posts:
    1
    Maybe i shouldn't reply to a thread this old but DOD scales nicely with DDD (data driven design) and is surprisingly not too difficult to program in, i'd argue it's actually immensely easier than OOP with large scale projects, it's just that newbs shy away from anything not OOP. On that note in this day and age ECS is finally catching on, and while it's not the only way to do things, it's already a plethora easier to maintain and scale. Performance AND game behavior, it's a full win. And virtual methods in C++ don't get loaded to a stack that makes no sense. Any data they create would though (unless new/malloc/static ect...), the actual code is in the .code segment of a program though. It's not that you have to use something like ECS for everything either even for engine programming (which i main in) the point is to just avoid indirection as much as possible, stop confusing things with useless abstractions that complicate the real problems, use existence based processing as much as possible, and put maintainability above fast prototyping if you're going to do a project for long periods of time. For example the devs of 7 days to die are honestly very dishonest with themselves in this regard. Unity isn't the engine for a game like that and even then they could've switched to DOTS or got a real low level programmer on board instead of pretending the game will magically get better. I am S*** talking a bit however mind i respect this engine more than UE4/UE5 because while the API here isn't the best with DOTS it already outperforms that and it doesn't force you toooooooo heavily into something as bullcrap as the actor pattern. Thanks to DOTS there's some amount of escape hatches.