Just realised I somehow managed to leave out an absolutely crucial piece of info: the code examples in the second half of the talk are specifically in C#, hence the way it stores structs and classes differently in arrays. In C/C++ the same principle does apply, but it's the difference between an array of classes, vs an array of pointers to classes 🙂 This talk was originally given at a game dev conference in New Zealand, to an audience of mostly Unity devs. Hence the C#!
@@sealsharp no I mean record struct. They have advantages like struct since value type plus class like access patterns (and immutability) plus stack allocation. record by itself equivalent to record class and is heap but has polymorphism.
@@CraigLuna yes, the immutability is what i thought you were referring to. For record struct, immutability is intended, but not enforced, you can add mutable properties. readonly struct really enforces immutability and thus is slightly better at preventing defensive copies, thought there are a lot of ways to accidentally do one anyways. The second feature of records, the autocreation of GetHashCode and Equals is also an interesting topic in terms of performance. I've seen it underperform in benchmarks compared to a manual GetHashCode. I generally agree with you that it would be a good idea to discuss the potential of immutable structs. 👍
@ it isn’t the immutability that matters in regards of this discussion but rather the ability to use class like patterns but with the memory advantages of a struct. Record struct is a great addition to the language with free performance perks.
I'm not sure why it was recommended either given the topic is pretty niche 😅 Glad you found it interesting though, I started down the rabbit hole myself a while back and it makes me happy to think this video might be a small part of other folks' journey!
Dude this is SUCH a good video... You made something I had zero knowledge of extremely easy to understand and even start implementing. Instant sub. Well done!!
Rule of thumb if you actually have to delete from a collection while iterating it: Loop from end to start instead of start to end (in this case "i--" instead of "i++" in the for). Not only will this naturally avoid holes, but as a side effect it also keeps the order. And in a lot of cases this also avoids potenial errors like out of bounds exception or even more fundamentally wrong operations (in terms of logic). E.g. if you'd just have a list of say integer values and you'd to something like "for (int i = 0; i < list.count, i++) { if (i == 4) list.removeAt(i--) }" this would cut everything after index 3 because i keeps shifting back i inside the loop.
Watching this geniunely assuming it had at least 100k views. Super clear and well put together talk that more people need to see. Often people see optimisation as just the annoying thing you do at the end to squeeze an extra bit of performance. However, 90% of the optimisation can be done for free by just not programming it to begin with in a way that pretends the machine's limitations dont exist.
Agree, one of the things that really surprised me when I was first learning to program in a more performant way was: "wow, it's really this easy?". So many performance own-goals in modern software development practise...
Thank you! Honestly I owe everything I spoke about in this talk to folks who came before me and put the effort into getting the knowledge out there. Casey Muratori, Mike Acton, Andrew Kelley, Jon Blow to name a few 🙂
@@nicbarkeragainSame list for me, however who is Andrew Kelley? If he has any unique DoD content please share. Found the famous Acton 2014 talk in October 2021 and it absolutely changed my life and coding, watched it tens of times. AWESOME channel you have. So sick of OOP slow bloated cross platform BS corporate programming culture. I want to be part of a counterreaction.
@@paulcosta8297Andrew Kelley is the creator of the Zig programming language. He has a Data-Oriented Programming talk that demonstrates practical examples of how to apply the techniques and shows how using those techniques made big performance improvements in the Zig compiler.
@@paulcosta8297 Andrew Kelley is the creator of the Zig language, he has a talk called "Practical DoD" here on youtube that is fantastic and I highly recommend!
This is great, one of the best explanations of data-oriented programing/structure optimization that I have seen. I saw this on my homepage, so I think you have been blessed by the algorithm.
I'm always surprised when such a niche topic get recommended to people 😅 glad you found it useful, it took quite a long time for the concepts to become clear and intuitive for me, so in some ways this video was an attempt to help short circuit that process for other people!
this honestly opened my eyes on optimization, i always saw it as a "bash your head until you found a better alg with lower big O", never realized how heavy memory access actually was
Saw your CLay video, got recommended this today in my feed. Watched it on my lunch break. Amazing work! Insta-share to all of my game dev circles. Masterclass quality right here. Thank you so much for your insightful, well-organized, well-presented thoughts. The world needs more of this kind of intermediate level content to help people transition from beginners to masters with real, applicable skills and best practices. I'm putting all of these optimizations into my prototype game right when I get home, just to practice! 😁 Keep 'em coming, I could watch this all day!
No worries at all, so glad you found it so useful! I can highly recommend Mike Acton's talks and Casey Muratori's "Performance Aware Programming" course if you're interested in diving deeper on this topic 🙂
At 41:08, this wasn’t really an issue with using strings. It was an issue with the json parser, since the json parser for every entry was calling strlen which basically iterates over every character until it finds the null terminator. So it was doing num_characters * num_entries iterations when it could have just cached the length doing just num_entries iterations. Similarly it was also adding the parsed results to an array, but naively iterating over the entire array every time it added to it, to check if it was a duplicate. It could have just used a hashmap.
I do believe it was actually bad coders as the problem. There are tons of efficient JSON parser implementations available, but the coder apparently decided to roll out his own.
Even though I knew most of things mentioned here, I never checked actual numbers and also found few new things. Thank you for this video. It would be really helpful for me when I started programming and was even now.❤
That's awesome to hear. I was totally radicalised the first time I saw "Data Oriented Design and C++" by Mike Acton. It seriously changed my life. I wish I had been taught that way from the ground up. The whole reason I made this talk in the first place was to give at the new zealand game developers conference, and I was hoping to give some of the younger folks there that same feeling and inspiration.
Great video! As someone who dabbled in C++ game programming 20-25 years ago, it's very reassuring to know these basic techniques still work after all this time.
This video is mind-boggling. I never knew about the cache levels and bytes storage with a string capturing a complete 8 byte set. Plus plus, the re-ordering of variables is just the cherry on top. Like such simple solutions to incorporate which helps us in the long run. Amazinggggggggg!!!!!!!! I learnt a lot of new things here today. Swapback array being one of them as well
Nic, thanks so much for posting such quality content. You have a real talent for teaching and breaking down concepts in fun, easy-to-follow and engaging ways. I‘ve watched lots of talks by Casey Muratori, Jonathan Blow, Mike Acton and the like on similar topics, but your presentation is now the one I would recommend as the best material on DOD on the internet, period. Also, your work on Clay proves you practice what you preach! It‘s a quality piece of software, thank you for your efforts! Wish you the best of luck with growing the channel and I hope you have fun making these videos :)
Thank you so much! Yes these videos are super fun to create, and I've got a much better process for doing it these days. Would you believe that this video was recorded in a single 52 minute take that took me weeks to memorize? 😅
@ I didn‘t realize it was a single take until now 🤯 And yeah, I‘ve given a couple of programming talks, so I have some idea how much work goes into a polished presentation. For example, I was discussing Brian Will‘s „Object Oriented Programming is Bad“ (which you also seem to take some inspiration from?) and even with the source material it took me several weeks to put together something cohesive that meets people where they are (in my company specifically). Anyway, love all of your examples that show actual code. I know it’s really hard to come up with something that isn’t too trivial but also not so complicated that it can’t be understood within a slide or two!
@@guywithcurlyhair I've never seen it, but I have a lot of respect for Brian Will so I'm going to go check it out right now 👍 And yeah the code examples / benchmarks were by far the most time consuming part, as Casey & Prime have been talking about recently, micro benchmarks are notoriously hard to get good results from and it was very fiddly to isolate specific effects that I wanted to demonstrate. I was very lucky that my work paid for me to make this talk because I gave it at the new zealand game developers conference, but doing it just for my personal stuff it's hard to justify putting so much effort into a single video haha
The analogy at the beginning was the right setup for the ideas coming after to be understood clearly and generate further thought just as clear. Excellent work Nic. Thanks.
My only qualm with the final optimization is you now make yourself vulnerable to the bug that the Enum solved for you initially but worse. You now have 3 possible arrays you could accidentally leave the enemy in, and unlike before where it would route to dead by default you can now run the death logic, then frenzy logic and then normal logic on the same enemy. Obviously, your 'enemyManager' class or whatever could handle it, but that does mean you may just be moving the cost of that operation to somewhere else. I don't think this detracts away from the actual point, or the other optimizations so it's a very minor nitpick. Thank you for the excellent video!
I agree, as we're getting towards the very end of the video these are optimisations that have specific use cases. As a general rule there is a point at which optimisation starts to make code more brittle, and should be used sparingly in performance critical situations. Being aware of the possibility though - that the tool exists - I think is still very important 🙂
This is one of the most informative videos I've ever watched in my life. I've been working with Unity for 10 years, and not once did any of these topics come up for any company I've worked with.
Wonderful rundown. I appreciated the table where each one's impact is called it separately. Also inclusion of "optimizations" that did not affect performance.
@Nic Yes please take us all the way to SIMD, parallelism, IPC and also more from your allocators topic. Really kooking forward to more videos from you. Keep up the awesome work!👍👍
With the GTA, the main problem was not 10mb string but the scanf implementation. When they use it to parse number like scanf(«%d… for some reason it was using strlen every time. So basically every scanf was calling strlen and strlen is O(n)
You're right, but the point I was more trying to get across was - likely at initial implementation or even release time it wasn't a noticeable issue (even _with_ calling strlen every single time), and it was only after the string grew in size that the overall performance degraded significantly. Strings are just full of performance foot guns like that which don't seem so bad but can come back to bite you later 🙂
@@nicbarkeragain kinda. I agree you need to avoid strings when you can, but most of the time you use them, so just you need to know how it actually works. More awareness, especially in gamedev
@@delphifeel That is something I 100% agree with. More awareness is so important. Most of the things I mentioned in this talk don't actually make any noticeable difference at the small scale. But the problem is if you don't understand them at all, eventually you'll write something large scale without realising how slow things can get.
excellent talk, my mind was blown the entire time at the start i thought i knew everything since ive implemented some of these changes myself, but then it just kept going.... will be showing to all of my colleagues !
Awesome, happy to spread the knowledge 😁 Can very highly recommend the two linked talks by Mike Acton and Andrew Kelley in the description, they're absolutely fantastic.
i'm basically a noob but this makes a lot of sense. watching as many of these type of videos to prep for data structures and algorithms class next semester. Thanks bro!
I still consider myself fairly new to game development and low-level programming in general. I’ve found it challenging to wrap my head around new ideas and let go of the old OOP mindset. However, this video does an exceptional job of explaining things using the analogy of a kitchen, which really helped me understand why DOD should be applied at any stage of development-at least to a degree. OOP languages like C# often cloud your thinking with layers of abstraction, making it easy to lose sight of how to speak the computer's language. Mike Acton’s talk perfectly emphasizes why we should avoid trying to adapt human language to programming, and this video reinforces that idea in such a clear and practical way.
Mix you are a true engineer. It's so nice to get such a deeply technical but well explained and easy to follow guide into the frankly fascinating world of game dev programming.
Fantastic video. I’ve already seen Andrew Kelley’s and Mike Acton’s classic talks, but it’s always nice to get a refresher. Your video is especially put together and well spoken, I’ll be recommending this to my programmer friends. Cheers
at 47:44 I'm confused on where you implement the logic for shifting an enemy from one array to the other when they no longer meet the criteria and how that affects performance. otherwise amazing talk!
Yes, that is what I was wondering about as well. You don't have to check the conditionals within the loop, but in the un-shown setup you would have to separate them into arrays based on that condition. btw I also enjoyed the talk.
Just out of curiosity, this is what I got from writing a similar project in Golang and applying the optimizations: ```csv method,time (ns/op),compared to previous (%),compared to baseline (%) FirstVersion,1164485,-,- InlineEnemyUpdate,1158264,99.47,99.47 InlineOnDeath,1070923,92.46,91.97 BetterOnDeath,308621,28.82,26.50 HoistedVars,299913,97.18,25.75 EnemyMemAligned,280461,93.51,24.08 GlobalMemAligned,273221,97.42,23.46 GameMemAligned,271614,99.41,23.32 EnemyStateInt,276126,101.66,23.71 EnemyStateUint8,272290,98.61,23.38 EnemyIdUintAndSprintf,243111,89.28,20.88 EnemyIdUintNoPrint,124530,51.22,10.69 DeleteAllDeadEnemiesAtTheEnd,105268,84.53,9.04 SwapbackDeleteSingle,97438,92.56,8.37 SwapbackDeleteMany,83539,85.74,7.17 OutOfBand,67171,80.41,5.77 ```
really good work dude, I'm a blueprint user in unreal, but have medium intimacy with C++ and some other languages and could understand it from start to finish. Got a subscriber
Wow! I'm a dev but I never did CS (physics background). I've never thought about things in this way. I was engaged the whole time, this was an awesome talk that really didn't feel like it was almost an hour.
It was difficult for me to understand data-oriented at first but I love it. It’s so simple and so much you can do with it. However the biggest issue for me is when you’re in a design team that still thinks the OOP way (and keeps changing their minds). It can become quite challenging to find a balance between the performant data-oriented design and the ‘flexible’ design that many designers expect. In my previous project, we took a data-oriented system but tried to simplify it for designers into a ‘capability-oriented’ system. It wasn’t so bad but after using it for about a year, it didn’t deliver the performance we needed for our scale so we essentially got the green light to tell the designers to suck it up and went full data-oriented.
You've just taught me more about programming in one video than the 4 year game dev college I graduated from in 2017.. I guess I'm gonna overhaul my entire codebase now :)
I probably wouldn’t suggest that. Data-oriented is great but to actually utilise it, you have to make all related systems data-oriented. This will usually include some kind of ECS system to properly organise this data, execute functions efficiently, and observe state changes. One of the main reasons for this is because of ‘vectorisation’. Data that is vectorised is fast to access and manipulate. But the cost of vectorising data is expensive. Sometimes this cost is more than what you save in your vectorised code. Therefore, in order to get the benefits of vectorisation without the disadvantages, you need to make sure your data is already vectorised to begin with (rest). This is completely against any OOP principle, which is why you need a new way of thinking to deal with it.
Great to hear, and I agree - I think there is a bit of a myth that performance only matters for high end games. It's important in non game software too!
Another name for the out of band technique is Existential Processing, it is explained in Data-Oriented Design by Richard Fabian. Also this book is really really good
I don't know what data oriented design is yet, as I've yet to watch this. But it sounds like the perfect name for how I've discovered is the best approach to understanding software and making well structured programs that are made to do what they need to do. Starting to analyze how the data will flow through technically, then attempting to add structure to that using the means of the programming language, without adding hoops for the data to jump through just to satisfy some clean coding mumbo jumbo.
Mind fucking blown. I love you This info is likely pretty well known to proper programmers with degrees. But for someone trying to learn programming by themselves, this is the kind of video that can 2X your understanding. I am very grateful for this
The importance of cache locality is such that in many cases, just doing a linear search over continually stored data is often faster than doing a binary search, moreso if there are few elements (by few I mean less than a couple thousands) just because continuous reading is easy to predict and the CPU will prefetch the data correctly
This is what i was looking for, please create more videos like this, if you get a good reach, you may as well do dome courses where you go all in in these kind of concepts, i always wanted something like this and more in depth, but usually all just hype-train/trend videos. subbed, liked, and i am waiting for more, bless you!
Very useful videos. A correction: GTA V JSON bug was caused by C-strings, they have O(n) on getting their size, they did for(size_t i = 0; i < size(config); i++) and got O(n^2). This is a famous issue with exactly C-strings, and although it is a good optimization to change id from string to something else, you shouldn’t worry about GTA V-size performance issues with C# strings - they are literally designed to solve C-string issues.
And this is only scratching the surface. At different scales of data (especially smaller ones), some "optimizations" might turn into making things slower instead because of the overhead involved in setting things up. Or if the data is part of different systems, an optimization in the data for one system might affect another system's performance negatively.
This is a very useful and entertaining breakdown of fundamentals. Fundamentals that I would imagine most professional game developers are very familiar with. I believe that given enough time, especially without periods of crunch, developers would put such methods into practice. However, with the increasing demand for maximum fidelity (either from consumers or higher-ups) teams are often overworked for the purpose of getting a product to a barely presentable state of function, with focus placed presentation. Rather than being the fault on any developer's lack of skill, the industry's optimization problem likely stems from a structural issue within companies whose goal is to churn out eye-candy that will move copies.
Some modern languages do! But for older ones (noteworthy in particular for C and C++) have it in their standards that structs should never be reordered on compile-time for the sake of binary interface stability
This would be much more interesting to see benchmarks on actors doing something in the world. Were the integer ids in your tests actually used to retrieve an enemy actor and call a function to execute something? What was the code actually doing? You need that integer id to get a pointer to some kind of data container and modify it and then the enemy needs to act on that new data.
Thanks, I was happy that it panned out so well! As it turns out, principles of efficient bulk processing are shared across lots of different environments and systems, not just in programming 🙂
47:51 Aren't we moving the division of enemies into three groups to some code above our function? I don't quite see the point of this optimization, as we'll still have to write a bunch of "if" statements elsewhere to divide the enemies into groups.
The idea is to move the if statements from the hot code. How often does an enemy goes frenzy(after 5 seconds?) or dies(after a 1 minute?) in comparison to "just do your regular" (30/60 times per second depending on your tick time.). There is some computational overhead to manage the lists but it must be much lower than checking it in every iteration. Not only are you skipping the check - you also are using CPU predictions and avoid costly rollbacks. At the end: Try it and measure it.
Just realised I somehow managed to leave out an absolutely crucial piece of info: the code examples in the second half of the talk are specifically in C#, hence the way it stores structs and classes differently in arrays. In C/C++ the same principle does apply, but it's the difference between an array of classes, vs an array of pointers to classes 🙂
This talk was originally given at a game dev conference in New Zealand, to an audience of mostly Unity devs. Hence the C#!
Time to discuss record struct in this optimization scenario!
@@CraigLuna Is there a performance benefit to records? Or did you mean "readonly struct"?
@@sealsharp no I mean record struct. They have advantages like struct since value type plus class like access patterns (and immutability) plus stack allocation. record by itself equivalent to record class and is heap but has polymorphism.
@@CraigLuna yes, the immutability is what i thought you were referring to. For record struct, immutability is intended, but not enforced, you can add mutable properties.
readonly struct really enforces immutability and thus is slightly better at preventing defensive copies, thought there are a lot of ways to accidentally do one anyways.
The second feature of records, the autocreation of GetHashCode and Equals is also an interesting topic in terms of performance. I've seen it underperform in benchmarks compared to a manual GetHashCode.
I generally agree with you that it would be a good idea to discuss the potential of immutable structs. 👍
@ it isn’t the immutability that matters in regards of this discussion but rather the ability to use class like patterns but with the memory advantages of a struct. Record struct is a great addition to the language with free performance perks.
I'm not sure why UA-cam recommended me this, but now I think I've found a new interest. Thank you so much for the video!
By "found a new interest", I mean learning how deep the optimisation rabbit hole goes. Also really fun to understand how the code is actually run.
I'm not sure why it was recommended either given the topic is pretty niche 😅 Glad you found it interesting though, I started down the rabbit hole myself a while back and it makes me happy to think this video might be a small part of other folks' journey!
Dude this is SUCH a good video... You made something I had zero knowledge of extremely easy to understand and even start implementing. Instant sub. Well done!!
So glad to hear that! I watched a few life changing videos on this subject matter, so it feels great to be able to pass some of it on.
This video/channel are criminally underrated
I'm more just happy that people are enjoying the videos, the numbers don't matter 🙂
Was that a combination of a compliment and a jab of the grammatical error referencing plural “knife”? 😂
@@larsoevlisen hahaha 110% a compliment! the level of quality and presentation are superb!
@@hectormejia499 😂
Its criminal for hardware sellers
This is actually a really well thought out explanation of performance optimization that was concise and clear as day. Thank you for making this.
Thanks, I think it took about 6 months in total from starting to collect notes to building the final talk, so I'm glad it came out well 🙂
Firstly I got recommend your video about Clay. Now UA-cam pushed this gem to me. Well done, Nic!
Glad you enjoyed it! This one took a lot of effort to make 😁
@@nicbarkeragain and it was well worth it
Rule of thumb if you actually have to delete from a collection while iterating it: Loop from end to start instead of start to end (in this case "i--" instead of "i++" in the for). Not only will this naturally avoid holes, but as a side effect it also keeps the order. And in a lot of cases this also avoids potenial errors like out of bounds exception or even more fundamentally wrong operations (in terms of logic). E.g. if you'd just have a list of say integer values and you'd to something like "for (int i = 0; i < list.count, i++) { if (i == 4) list.removeAt(i--) }" this would cut everything after index 3 because i keeps shifting back i inside the loop.
Watching this geniunely assuming it had at least 100k views. Super clear and well put together talk that more people need to see. Often people see optimisation as just the annoying thing you do at the end to squeeze an extra bit of performance. However, 90% of the optimisation can be done for free by just not programming it to begin with in a way that pretends the machine's limitations dont exist.
Agree, one of the things that really surprised me when I was first learning to program in a more performant way was: "wow, it's really this easy?". So many performance own-goals in modern software development practise...
I absolutely need more talks like this from you on other game engine architecture topics.
I'm definitely planning a lot more educational videos like this in the new year 😁
Just need architectural talks lmao 🤣🤣
This video is criminally under-viewed. It should be seen by all programmers.
Thank you! Honestly I owe everything I spoke about in this talk to folks who came before me and put the effort into getting the knowledge out there. Casey Muratori, Mike Acton, Andrew Kelley, Jon Blow to name a few 🙂
@@nicbarkeragainSame list for me, however who is Andrew Kelley? If he has any unique DoD content please share. Found the famous Acton 2014 talk in October 2021 and it absolutely changed my life and coding, watched it tens of times. AWESOME channel you have. So sick of OOP slow bloated cross platform BS corporate programming culture. I want to be part of a counterreaction.
@@paulcosta8297Andrew Kelley is the creator of the Zig programming language. He has a Data-Oriented Programming talk that demonstrates practical examples of how to apply the techniques and shows how using those techniques made big performance improvements in the Zig compiler.
@@paulcosta8297 Andrew Kelley is the creator of the Zig language, he has a talk called "Practical DoD" here on youtube that is fantastic and I highly recommend!
it's not underviewed. the camera is basically above the guy
This is great, one of the best explanations of data-oriented programing/structure optimization that I have seen.
I saw this on my homepage, so I think you have been blessed by the algorithm.
I'm always surprised when such a niche topic get recommended to people 😅 glad you found it useful, it took quite a long time for the concepts to become clear and intuitive for me, so in some ways this video was an attempt to help short circuit that process for other people!
this honestly opened my eyes on optimization, i always saw it as a "bash your head until you found a better alg with lower big O", never realized how heavy memory access actually was
Saw your CLay video, got recommended this today in my feed. Watched it on my lunch break. Amazing work!
Insta-share to all of my game dev circles. Masterclass quality right here. Thank you so much for your insightful, well-organized, well-presented thoughts. The world needs more of this kind of intermediate level content to help people transition from beginners to masters with real, applicable skills and best practices.
I'm putting all of these optimizations into my prototype game right when I get home, just to practice! 😁 Keep 'em coming, I could watch this all day!
No worries at all, so glad you found it so useful! I can highly recommend Mike Acton's talks and Casey Muratori's "Performance Aware Programming" course if you're interested in diving deeper on this topic 🙂
At 41:08, this wasn’t really an issue with using strings. It was an issue with the json parser, since the json parser for every entry was calling strlen which basically iterates over every character until it finds the null terminator. So it was doing num_characters * num_entries iterations when it could have just cached the length doing just num_entries iterations.
Similarly it was also adding the parsed results to an array, but naively iterating over the entire array every time it added to it, to check if it was a duplicate. It could have just used a hashmap.
I do believe it was actually bad coders as the problem. There are tons of efficient JSON parser implementations available, but the coder apparently decided to roll out his own.
dont use json
Sounds like the issue was C strings. They wouldn't need strlen if the length was stored with the data
Even though I knew most of things mentioned here, I never checked actual numbers and also found few new things. Thank you for this video. It would be really helpful for me when I started programming and was even now.❤
That's awesome to hear. I was totally radicalised the first time I saw "Data Oriented Design and C++" by Mike Acton. It seriously changed my life. I wish I had been taught that way from the ground up. The whole reason I made this talk in the first place was to give at the new zealand game developers conference, and I was hoping to give some of the younger folks there that same feeling and inspiration.
@nicbarkeragain That is really cool.
This was gold, the perfect density of information and pace for me, so good
Glad you enjoyed it! The pacing was something I put a lot of work into, so I'm glad it shows.
He who has mastered Data Oriented Design, has mastered the act of distributing density of -data- information and pace of their content.
Great video! As someone who dabbled in C++ game programming 20-25 years ago, it's very reassuring to know these basic techniques still work after all this time.
The more things change, the more they stay the same 🙂
This video is mind-boggling. I never knew about the cache levels and bytes storage with a string capturing a complete 8 byte set. Plus plus, the re-ordering of variables is just the cherry on top. Like such simple solutions to incorporate which helps us in the long run. Amazinggggggggg!!!!!!!!
I learnt a lot of new things here today. Swapback array being one of them as well
I have a feeling this channel is about to get a lot of foot traffic - the quality is insane
Thank you, I'm glad you enjoyed the video 🙂
ultra-cool af. i learned new programming tips/tricks.
Nic, thanks so much for posting such quality content. You have a real talent for teaching and breaking down concepts in fun, easy-to-follow and engaging ways.
I‘ve watched lots of talks by Casey Muratori, Jonathan Blow, Mike Acton and the like on similar topics, but your presentation is now the one I would recommend as the best material on DOD on the internet, period.
Also, your work on Clay proves you practice what you preach! It‘s a quality piece of software, thank you for your efforts!
Wish you the best of luck with growing the channel and I hope you have fun making these videos :)
Thank you so much! Yes these videos are super fun to create, and I've got a much better process for doing it these days. Would you believe that this video was recorded in a single 52 minute take that took me weeks to memorize? 😅
@ I didn‘t realize it was a single take until now 🤯
And yeah, I‘ve given a couple of programming talks, so I have some idea how much work goes into a polished presentation.
For example, I was discussing Brian Will‘s „Object Oriented Programming is Bad“ (which you also seem to take some inspiration from?) and even with the source material it took me several weeks to put together something cohesive that meets people where they are (in my company specifically).
Anyway, love all of your examples that show actual code. I know it’s really hard to come up with something that isn’t too trivial but also not so complicated that it can’t be understood within a slide or two!
@@guywithcurlyhair I've never seen it, but I have a lot of respect for Brian Will so I'm going to go check it out right now 👍
And yeah the code examples / benchmarks were by far the most time consuming part, as Casey & Prime have been talking about recently, micro benchmarks are notoriously hard to get good results from and it was very fiddly to isolate specific effects that I wanted to demonstrate. I was very lucky that my work paid for me to make this talk because I gave it at the new zealand game developers conference, but doing it just for my personal stuff it's hard to justify putting so much effort into a single video haha
The analogy at the beginning was the right setup for the ideas coming after to be understood clearly and generate further thought just as clear. Excellent work Nic. Thanks.
This cooking analogy is incredibly intuitive and well-explained - thank you for making this ^^
That's valuable information about optimization. Really Thank you.
this is the third video I've watched from beginning to end. I should have subscribed two videos ago, great content.
My only qualm with the final optimization is you now make yourself vulnerable to the bug that the Enum solved for you initially but worse. You now have 3 possible arrays you could accidentally leave the enemy in, and unlike before where it would route to dead by default you can now run the death logic, then frenzy logic and then normal logic on the same enemy.
Obviously, your 'enemyManager' class or whatever could handle it, but that does mean you may just be moving the cost of that operation to somewhere else.
I don't think this detracts away from the actual point, or the other optimizations so it's a very minor nitpick. Thank you for the excellent video!
I agree, as we're getting towards the very end of the video these are optimisations that have specific use cases. As a general rule there is a point at which optimisation starts to make code more brittle, and should be used sparingly in performance critical situations. Being aware of the possibility though - that the tool exists - I think is still very important 🙂
Absolutely priceless knowledge, your explanations are great!
This is one of the most informative videos I've ever watched in my life. I've been working with Unity for 10 years, and not once did any of these topics come up for any company I've worked with.
I just went and watched a few other presentations on this topic after watching this. Your delivery of the content is by far the best, well done mate.
No clue why the algorithm decided to give this to me, but I’m grateful it did. Good presentation, well structured
Thank you! Glad you stumbled on it 😁
heyy, me too!
Wonderful rundown. I appreciated the table where each one's impact is called it separately. Also inclusion of "optimizations" that did not affect performance.
@Nic Yes please take us all the way to SIMD, parallelism, IPC and also more from your allocators topic.
Really kooking forward to more videos from you. Keep up the awesome work!👍👍
Amazing content! Thank you!
With the GTA, the main problem was not 10mb string but the scanf implementation. When they use it to parse number like scanf(«%d… for some reason it was using strlen every time. So basically every scanf was calling strlen and strlen is O(n)
You're right, but the point I was more trying to get across was - likely at initial implementation or even release time it wasn't a noticeable issue (even _with_ calling strlen every single time), and it was only after the string grew in size that the overall performance degraded significantly. Strings are just full of performance foot guns like that which don't seem so bad but can come back to bite you later 🙂
@@nicbarkeragain kinda. I agree you need to avoid strings when you can, but most of the time you use them, so just you need to know how it actually works. More awareness, especially in gamedev
@@delphifeel That is something I 100% agree with. More awareness is so important. Most of the things I mentioned in this talk don't actually make any noticeable difference at the small scale. But the problem is if you don't understand them at all, eventually you'll write something large scale without realising how slow things can get.
100 percent
excellent talk, my mind was blown the entire time
at the start i thought i knew everything since ive implemented some of these changes myself, but then it just kept going....
will be showing to all of my colleagues !
Awesome, happy to spread the knowledge 😁 Can very highly recommend the two linked talks by Mike Acton and Andrew Kelley in the description, they're absolutely fantastic.
Don’t do game dev but a lot of what you spoke about was transferable to normal software development in many languages. Good stuff 🎉
This is incredible.
Great talk, learned a lot. Many thanks.
i'm basically a noob but this makes a lot of sense. watching as many of these type of videos to prep for data structures and algorithms class next semester. Thanks bro!
Thank you for putting this video together!
Great stuff! Deserves way more views!
You're welcome, great that you got something useful out of it 🙂
So freaking good. Thank you this is awesome.
Thanks Will, glad you enjoyed it.
The kitchen analogy is the best analogy I have ever seen and I'll use it from now on every time I'm describing anything happening in a cpu.
It works surprisingly well! Turns out there are a lot of similarities between realtime systems 😁
The detailed and in-depth explanation was impressive, truly mind-blowing.
I still consider myself fairly new to game development and low-level programming in general. I’ve found it challenging to wrap my head around new ideas and let go of the old OOP mindset. However, this video does an exceptional job of explaining things using the analogy of a kitchen, which really helped me understand why DOD should be applied at any stage of development-at least to a degree.
OOP languages like C# often cloud your thinking with layers of abstraction, making it easy to lose sight of how to speak the computer's language. Mike Acton’s talk perfectly emphasizes why we should avoid trying to adapt human language to programming, and this video reinforces that idea in such a clear and practical way.
Mix you are a true engineer. It's so nice to get such a deeply technical but well explained and easy to follow guide into the frankly fascinating world of game dev programming.
Thank you, I appreciate that! Game dev is fun, you should try 😁
Amazing talk, thank you!
Very helpful - I don't even do game dev. Thanks for all the detailed explanations.
The best video for data oriented design I have seen so far.
Fantastic video. I’ve already seen Andrew Kelley’s and Mike Acton’s classic talks, but it’s always nice to get a refresher. Your video is especially put together and well spoken, I’ll be recommending this to my programmer friends. Cheers
Great and fun video^^ Glad to see your explanations paired with examples. Thanks!
Such a great talk! Thank you!
You're welcome!
Thank God for putting actually engaging coding content on my feed today
at 47:44 I'm confused on where you implement the logic for shifting an enemy from one array to the other when they no longer meet the criteria and how that affects performance. otherwise amazing talk!
Yes, that is what I was wondering about as well. You don't have to check the conditionals within the loop, but in the un-shown setup you would have to separate them into arrays based on that condition. btw I also enjoyed the talk.
He meant that whenever you are supposed to set the variables (for example, enemy.dead = true) you would instead move them in the arrays.
@@mrglick5050 Okay. So for example, when it dies get rid of it with "swapback" array methods and add it to the array for the dead. Thanks!
this info is so useful, can't believe I've never heard of like any of this!
It changed my life the first time I saw a video explaining these concepts, I wanted to pass it on!
You're a good teacher with great analogies.
I learned so much from this video! Thank you!
Just out of curiosity, this is what I got from writing a similar project in Golang and applying the optimizations:
```csv
method,time (ns/op),compared to previous (%),compared to baseline (%)
FirstVersion,1164485,-,-
InlineEnemyUpdate,1158264,99.47,99.47
InlineOnDeath,1070923,92.46,91.97
BetterOnDeath,308621,28.82,26.50
HoistedVars,299913,97.18,25.75
EnemyMemAligned,280461,93.51,24.08
GlobalMemAligned,273221,97.42,23.46
GameMemAligned,271614,99.41,23.32
EnemyStateInt,276126,101.66,23.71
EnemyStateUint8,272290,98.61,23.38
EnemyIdUintAndSprintf,243111,89.28,20.88
EnemyIdUintNoPrint,124530,51.22,10.69
DeleteAllDeadEnemiesAtTheEnd,105268,84.53,9.04
SwapbackDeleteSingle,97438,92.56,8.37
SwapbackDeleteMany,83539,85.74,7.17
OutOfBand,67171,80.41,5.77
```
really good work dude, I'm a blueprint user in unreal, but have medium intimacy with C++ and some other languages and could understand it from start to finish. Got a subscriber
Wow! I'm a dev but I never did CS (physics background). I've never thought about things in this way. I was engaged the whole time, this was an awesome talk that really didn't feel like it was almost an hour.
This talk was immensely helpful.
Thank you very much for putting it on UA-cam, as I can now refresh my memory every so often.
Glad you enjoyed it 🙂
You explained everything so simply, gamedevs are a different breed.
Great video, very informative!
Thanks, really appreciate that!
It was difficult for me to understand data-oriented at first but I love it. It’s so simple and so much you can do with it.
However the biggest issue for me is when you’re in a design team that still thinks the OOP way (and keeps changing their minds).
It can become quite challenging to find a balance between the performant data-oriented design and the ‘flexible’ design that many designers expect.
In my previous project, we took a data-oriented system but tried to simplify it for designers into a ‘capability-oriented’ system. It wasn’t so bad but after using it for about a year, it didn’t deliver the performance we needed for our scale so we essentially got the green light to tell the designers to suck it up and went full data-oriented.
Fantastic video! I wish I would have seen it earlyer
There are no words that would adequately describe how great this video is
So glad to hear you enjoyed it! I owe so much to the people who's videos taught me - Mike Acton, Casey Muratori, Andrew Kelley, Jon Blow etc
Great talk! And I think a wonderful introduction to the topic.
You've just taught me more about programming in one video than the 4 year game dev college I graduated from in 2017.. I guess I'm gonna overhaul my entire codebase now :)
I probably wouldn’t suggest that.
Data-oriented is great but to actually utilise it, you have to make all related systems data-oriented. This will usually include some kind of ECS system to properly organise this data, execute functions efficiently, and observe state changes.
One of the main reasons for this is because of ‘vectorisation’.
Data that is vectorised is fast to access and manipulate. But the cost of vectorising data is expensive. Sometimes this cost is more than what you save in your vectorised code.
Therefore, in order to get the benefits of vectorisation without the disadvantages, you need to make sure your data is already vectorised to begin with (rest). This is completely against any OOP principle, which is why you need a new way of thinking to deal with it.
Really enjoyed this talk. Thanks for posting!
Thanks for watching it!
Excellent 👌 Hey UA-cam recommend me more of this type of videos please!
Check out "Data Oriented Design and C++ by Mike Acton" if you're looking for the most amazing video on this topic!
@@nicbarkeragainthank you I've added it to my watch list.
Woooow! This is such a good video. I actually watched the whole thing. The chef and kitchen thing is a good way to explain it.
Thanks, great video!
This is incredible stuff! Insightful for non gamedev too.
Great to hear, and I agree - I think there is a bit of a myth that performance only matters for high end games. It's important in non game software too!
Another name for the out of band technique is Existential Processing, it is explained in Data-Oriented Design by Richard Fabian. Also this book is really really good
Thanks for the recommendation, I'll have to check the book out!
I don't know what data oriented design is yet, as I've yet to watch this.
But it sounds like the perfect name for how I've discovered is the best approach to understanding software and making well structured programs that are made to do what they need to do. Starting to analyze how the data will flow through technically, then attempting to add structure to that using the means of the programming language, without adding hoops for the data to jump through just to satisfy some clean coding mumbo jumbo.
amazing video, you have earned a subscriber
Great to hear that you enjoyed it! It took a very long time to design, research and memorise so I'm glad people are getting some value out of it haha
what an amazing video, thank you very much for this !!
Mind fucking blown. I love you
This info is likely pretty well known to proper programmers with degrees. But for someone trying to learn programming by themselves, this is the kind of video that can 2X your understanding. I am very grateful for this
The importance of cache locality is such that in many cases, just doing a linear search over continually stored data is often faster than doing a binary search, moreso if there are few elements (by few I mean less than a couple thousands) just because continuous reading is easy to predict and the CPU will prefetch the data correctly
Always start with a good old linear scan, build an acceleration structure if it gets too slow 😁
This is what i was looking for, please create more videos like this, if you get a good reach, you may as well do dome courses where you go all in in these kind of concepts, i always wanted something like this and more in depth, but usually all just hype-train/trend videos. subbed, liked, and i am waiting for more, bless you!
Very useful videos. A correction: GTA V JSON bug was caused by C-strings, they have O(n) on getting their size, they did for(size_t i = 0; i < size(config); i++) and got O(n^2). This is a famous issue with exactly C-strings, and although it is a good optimization to change id from string to something else, you shouldn’t worry about GTA V-size performance issues with C# strings - they are literally designed to solve C-string issues.
Now it clicked for me - i watched andrew kellys "Data oriented design in practice", but this video presenta the idea much better!
That talk was a huge inspiration for this video!
Amazing video, very informative, well presented and inspirational, thank you!
Thank you! My programming career was incredibly influenced by great talks that I saw, so I hope I can pass that tradition on to others.
Another winner! Thanks Nic👍
Glad you like it 😁 this one took a very long time to make (probably 80+ hours just to research and write the talk alone)
wow, what a great video!
Thank you, I'm glad you found it interesting!
this is excellent!
As someone who can't code to save their life, this fantastic video had me glued to the screen. I never knew optimization could be so interesting
And this is only scratching the surface.
At different scales of data (especially smaller ones), some "optimizations" might turn into making things slower instead because of the overhead involved in setting things up. Or if the data is part of different systems, an optimization in the data for one system might affect another system's performance negatively.
This is a very useful and entertaining breakdown of fundamentals. Fundamentals that I would imagine most professional game developers are very familiar with. I believe that given enough time, especially without periods of crunch, developers would put such methods into practice. However, with the increasing demand for maximum fidelity (either from consumers or higher-ups) teams are often overworked for the purpose of getting a product to a barely presentable state of function, with focus placed presentation. Rather than being the fault on any developer's lack of skill, the industry's optimization problem likely stems from a structural issue within companies whose goal is to churn out eye-candy that will move copies.
Great video, lots of these concepts also apply in GPU computing
Absolutely. Small, tightly packed and predictable data is foundational for performance in basically all computing paradigms.
Why compiler don't do alignment 36:00 automatically? It looks like this can be easily done by compiler automatically.
maybe its something with c# but idk because i dont use c#
Some modern languages do! But for older ones (noteworthy in particular for C and C++) have it in their standards that structs should never be reordered on compile-time for the sake of binary interface stability
This would be much more interesting to see benchmarks on actors doing something in the world.
Were the integer ids in your tests actually used to retrieve an enemy actor and call a function to execute something? What was the code actually doing?
You need that integer id to get a pointer to some kind of data container and modify it and then the enemy needs to act on that new data.
Awesome video, super educational!
Awesome video! Very clean display of info
Glad you enjoyed it!
Absolute gem, great to find you in this mess.
Thanx man, learned a lot
Outstanding.
Thank you!
This is a fantastic talk, I only wish you'd added chapters!
Cool stuff! Learned a bit. :)
pure gold!
Thank you, glad you enjoyed it!
Loved the analogy of Restaurants!
Thanks, I was happy that it panned out so well! As it turns out, principles of efficient bulk processing are shared across lots of different environments and systems, not just in programming 🙂
47:51
Aren't we moving the division of enemies into three groups to some code above our function?
I don't quite see the point of this optimization, as we'll still have to write a bunch of "if" statements elsewhere to divide the enemies into groups.
The idea is to move the if statements from the hot code. How often does an enemy goes frenzy(after 5 seconds?) or dies(after a 1 minute?) in comparison to "just do your regular" (30/60 times per second depending on your tick time.). There is some computational overhead to manage the lists but it must be much lower than checking it in every iteration. Not only are you skipping the check - you also are using CPU predictions and avoid costly rollbacks.
At the end: Try it and measure it.
Thanks a lot, that's mind changing
Glad you found it useful!