Data-Oriented Demo: SOA, composition

  Рет қаралды 153,440

Jonathan Blow

Jonathan Blow

9 жыл бұрын

In this demo we start to do some 'object-system-ish' stuff, but with a data-oriented mindset. The goal is: how do we recreate some of the high-level expressiveness you get in a language like C++, but in a way that helps make your program fast?

Пікірлер: 183
@bus
@bus 6 жыл бұрын
Just in case somebody's watching this just now: Jon said recently that the SOA feature is not in the language anymore, but it will be brought back in a different way that is more generic and useful for more things.
@metalim
@metalim 5 жыл бұрын
SOA = Structures of Arrays.
@rustydagger456
@rustydagger456 5 жыл бұрын
^ ^ ^ I'd also like to know where, I'm curious about the reason/ing
@0xCAFEF00D
@0xCAFEF00D 5 жыл бұрын
I'm guessing it's some twitch stream.
@needlessoptions
@needlessoptions 4 жыл бұрын
He's demoed it now bois, it's one of his most recent videos here on KZbin
@PhyloGenesis
@PhyloGenesis Жыл бұрын
This is a super helpful comment, thank you! I'm just learning about this language and watching through all these so the heads up is great.
@AlanBalls
@AlanBalls 9 жыл бұрын
You can do this in C++! **posts nightmare code**
@Kavukamari
@Kavukamari 6 жыл бұрын
thanks, satan!
@zemlidrakona2915
@zemlidrakona2915 3 жыл бұрын
Yes you can do it in C++, I'm not sure what *post nightmare code* means since to me nightmare code is (a) subjective and (b) the fault of the programmer.
@RicardoDelfinGarcia
@RicardoDelfinGarcia 3 жыл бұрын
@@zemlidrakona2915 You forgot option (c): a joke by op
@miko007
@miko007 3 жыл бұрын
actually, you now can really do this in c++. the using keyword since c++17 now does exactly that. maybe the committee finally borrowed an idea from blow :D
@bra5081
@bra5081 3 жыл бұрын
@@zemlidrakona2915 Nightmare code is when one has to read code written by others. :o
@jonkrieger5271
@jonkrieger5271 9 жыл бұрын
Thanks for the links about Data-Oriented at 16:31 - yes this is me lazily providing myself a link back to that point in the video :)
@paulusul
@paulusul 5 жыл бұрын
Mike Acton, "Data-Oriented Design and C++" kzbin.info/www/bejne/qImTeqeMerudfsU
@anonymous4711_
@anonymous4711_ 4 жыл бұрын
@@JustMe-fl1db the real MVP right here
@walter0bz
@walter0bz 9 жыл бұрын
Been through the pain of refactoring OOP virtual based code on the xbox 360, splitting data up for DMA into SPUs on the ps3.. etc. this is a really nice idea.. being able to chop & change data layout without having to butcher source too much. It is indeed a big deal that the language herds you in one direction with its' inbuilt syntax IMO.
@VoyivodaFTW1
@VoyivodaFTW1 Жыл бұрын
I think it this is one of the side effects of these programming language wars. The neck beards wanted to build stuff, while corporations wanted to force people into buying into their ecosystem. I feel like this hurt programmers and customers the most, because of all the bad code that came from incorrect OOP implementations resulting in just plain bad software. Now that we know more about the importance and usefulness in considering the relationship of how CPUs like to have data laid out, things seem to be coalescing towards more flexible designs that consider the data being worked on/ the problem being solved and not the language a program is written in.
@DouglasGregoryTO
@DouglasGregoryTO 9 жыл бұрын
I cannot "Like" this enough. Ever since I learned about data-oriented design, I've wanted to do stuff like this, and had a vague sense that a compiler *should* be able to let us write familiar AoS-style syntax describing fast SoA access... but I lacked the deep insight to say exactly how. Now I really really want to use this language. :D
@EricLaForest
@EricLaForest 9 жыл бұрын
Sounds good, but I wish there was a written explanation.
@DouglasGregoryTO
@DouglasGregoryTO 9 жыл бұрын
It's still a work in progress, so I'm sure there will be one eventually. Want me to try to summarize here, or did you already watch it?
@EricLaForest
@EricLaForest 9 жыл бұрын
A quick summary would be nice. Please.
@DouglasGregoryTO
@DouglasGregoryTO 9 жыл бұрын
One is a neat flavour of inheritance, where struct A can say it is "using" struct B. All of B's members are then available as members of A. So far it's like C++ inheritance, in that A inherits all of B's members and can implicitly cast to B. But it also works with multiple inheritance ("using" multiple other structs), or defining that you only want a pointer to a B instance to be stored with A, rather than storing B contiguously within the A instance. This lets you do many kinds of transformation on how your data is defined and laid out in memory, without any changes to the code that is acting on the data. One use case is splitting an entity into a hot and cold component, stored in two parallel arrays (to maximize cache efficiency for high-frequency traversals/modifications to the hot members), with the flexibility to easily change which members belong in which part (even switching it based on the compile target, to optimize for different systems' cache characteristics) He shows how this can be used to implement vTables for other familiar inheritance benefits, but this isn't yet a core language feature so it's a bit verbose just now. He also allows defining an array as SOA, so it will store all instances' values for each member contiguously, but still let you access it in the familiar array_of_entities[i].member syntax. You can also add an SOA mark at the definition of the type, so that all arrays of that type (unless explicitly marked AOS) immediately become SOA, again transforming data layout without requiring changes to other code. (Pointers to instances implicitly become SOA pointers, which are larger due to the extra metadata, but if you're switching to SOA then you're probably in a use case with more sequential buffer traversal than pointer-chasing anyway. He's also got some neat tricks with "using" a function to decompress pointers from a significantly smaller ID value) The philosophy behind this project (and I recommend checking out the whole playlist) is that code evolves over time, and that incremental changes to the program's function should not require discontinuous changes to swaths of your code. So far, even at the basic level of my coding, there's a pile of stuff that I'd find useful - like not having to refactor my foreach loops into for(i = 0; i < limit; i++) anytime I need access to the index within an iteration. ;)
@EricLaForest
@EricLaForest 9 жыл бұрын
Very cool. Thanks for writing that summary. It's also a little over my level of OOP, but I get the gist of it. It sounds very good.
@rtvdenys
@rtvdenys 3 ай бұрын
"using" is very much like "with ... " in Pascal. Yours is, of course, much more powerful. I am baffled as to why such a useful construct is not present in the vast majority of programming language. Well done for adding it. Special kudos for SOA. It is such a pain to do this manually.
@thund7963
@thund7963 9 жыл бұрын
I tried to implement something like that "using" keyword in C++, but it was impossible for me to do so in a simple manner. Good feature. What I like the most is that you are not sticking to the old dogmas (as opposed to what some so-academic people do), you know, "this has been done this way always! why should we change it?" or "It cannot be done!". Even if you are right or not, that does not matter, the main point is that you are doing experiments in the right direction thinking about real problems. I'm sure many people will come after you and will contribute to improve what you are doing, and that's great.
@majidarifs
@majidarifs 9 жыл бұрын
Love the videos, first saw you on a documentary about Indie Games. Have been a fan ever since. Very excited about the new language :)
@nintendude794
@nintendude794 2 жыл бұрын
Indie Game: The Movie?
@Dengakuman22
@Dengakuman22 9 жыл бұрын
Ok, door_test_4 was like: Why doesn't this exist already? Keep up the good work! This is starting to look awesome.
@JoshStefanski
@JoshStefanski 9 жыл бұрын
Just to toss in some food for thought, the 'mixin' idea came to mind for the use of 'using' with structs as it seems to describe the resulting behavior fairly well. However, 'mixin' might feel a bit awkward if used in the context of function arguments and code blocks. I really love the work going on here and can't wait to get my hands on it. Thanks for exploring this space!
@hwstar9416
@hwstar9416 Жыл бұрын
agreed. it can be weird reading entity.pos.x and somewhere else entity.x when they both access the same member.
@digitalconsciousness
@digitalconsciousness 3 жыл бұрын
9:22 The main challenge / puzzle to solve when using a DOD approach. You hit the nail on the head. 18:15 Again, talking about what we want with DOD, but we don't immediately have. 24:44 The concept of using 'using' to refer to members without using classes. 37:40 Creating new objects creates them in random places on the heap, which DOD tries to get away from, so... 39:00 ...a better way to do it using a namespace and pointers. SOA (structure of arrays). and that is what the rest of the video is mostly about, it appears.
@HiAdrian
@HiAdrian 9 жыл бұрын
Coincidentally I was looking you up yesterday, wondering if anything new on the language had surfaced on the web. This is a nice surprise.
@Maldito011316
@Maldito011316 9 жыл бұрын
Great video, Jonathan!! I'm enjoying it as I watch in parts. Keep it up! :D
@taylorius
@taylorius 9 жыл бұрын
I think your new language is enormously exciting. The OO hierarchy is rarely a perfect fit for a problem (why would it be?). Your method allows much richer, more flexible constructions, I especially love the cross cutting power. I would ditch C++ and use such a language tomorrow, without question. I was slightly disappointed with the section where you were "using" a function within your structure to manage access to a global array. This feature was really great, but then you seemed to back away from its full implications. You mentioned that it was NOT dynamic dispatch - which confused me, as it seemed as if the compiler could sort it out unambiguously. Anyway, for what its worth, I would say let the user write whatever functions they like in that situation - though the chances are I've not thought things through properly! Great work Jonathan, and my best wishes for this language's ongoing development!
@jblow888
@jblow888 9 жыл бұрын
The problem is that if you decide to use this for dynamic dispatch, you make it a lot slower, because the compiler has to re-call the function any time it thinks the result might be different. And because of aliasing problems, that is going to happen almost always. So you would end up calling the function tons of times, and it becomes slow. Whereas if you say this is just intended to be static dispatch with a compressed pointer, it can be very fast.
@taylorius
@taylorius 9 жыл бұрын
Jonathan Blow Thanks for replying. I can certainly see what you mean from a speed point of view - I suppose I saw that feature as having value beyond just being super fast. It seemed like a sort of operator overloading for structure dereferencing, which struck me as rather powerful. It could certainly contribute to your goal of a changing data layout requiring minimal code changes. Perhaps if arbitrary functions were allowed, there could be some sort of "static" keyword on the function, which could flag it as being simple, in the sense of always returning the same thing for a given input. The compiler could then do all the optimizations you mentioned. All the best!
@jblow888
@jblow888 9 жыл бұрын
Matthew Taylor In the past day or two I have thought about this more and in fact did think of tagging functions or variables with "static" to indicate that they don't change. So this might be the way the language goes in the future. It would definitely be in line with "make sure programs are correct first, but make it easy to make them fast".
@iceX33
@iceX33 8 жыл бұрын
+Jonathan Blow I see this feature as a lazy evaluation. When the entity is accessed first time the procedure is called and the result is stored (lazy evaluation). The using keyword only makes sure that the evaluation is transparent for the caller. The only question for me is if you want to let users replace the value or invalidate the result. I guess it is a bit harder because the value is anonymous. Only the name of procedure is exposed. Maybe NAME_OF_PROCEDURE_value to make it accessible.
@_profan
@_profan 9 жыл бұрын
This is incredibly interesting, and it's actually rather surprising no-one has thought of something like this for data layout in memory before. I feel rather inspired after watching this, and may take a stab at implementing something similar (albeit slightly contrived) with the aid of templates in D (accessing data laid out in SOA as if it was AOS).
@jblow888
@jblow888 9 жыл бұрын
Someone linked me already to a D implementation of a subset of this stuff... you might want to search for that as a starting point.
@_profan
@_profan 9 жыл бұрын
Just found the implementation, appreciate the info! These things are easy to miss in small communities.
@kcarlsson89
@kcarlsson89 6 жыл бұрын
A similar thing for Julia: github.com/simonster/StructsOfArrays.jl.
@notsoren665
@notsoren665 2 жыл бұрын
Jonathan has had the same character development as Saitama. As he becomes a better programmer he loses more hair.
@solhsa
@solhsa 9 жыл бұрын
I pondered whether "embed" would be better than "using" inside struct.. or "collapse", but after some thought I think using "using" everywhere is better.
@GingerGames
@GingerGames 9 жыл бұрын
I am already loving the language. This data-oriented approach is actually simple(r) in your language than others (especially C++)! The 'using' keyword doesn't need to be changed. It's pretty clear what is does (even if it technically means different things). This is opposite where in C/C++ 'static' keyword means many different things (global, internal, local persist, etc.) (I make it clearer by doing #define global static, etc.) Would it be possible for operator overloading? I don't like using it that often in C++ but when I do, it is usually to implement a math library (Vectors, Matrices, Quaternions, etc.) as it is much more natural to write code with these types where the operators are overloaded. Would it be possible to just view the code for the demos and invaders example (not the compiler) to get a better understanding of the language and to suggest more ideas?
@TheXello
@TheXello 5 жыл бұрын
I am excited to use this language in my own projects.
@kazriko
@kazriko 6 жыл бұрын
You answered my question on a prior video before I posed it, nice.
@Vesuvian
@Vesuvian 9 жыл бұрын
It's looking great! I really can't wait to start using this full time. These demos are equally exciting and depressing because I'll probably still be stuck with C++ for at least the next few years and converting my entire code base will not be too fun. How long after The Witness is finished do you think it will be until the language is production ready and your using it for your next game?
@bubbymcgee7601
@bubbymcgee7601 7 ай бұрын
a long time apparently 😭😭😭
@TECHN01200
@TECHN01200 11 ай бұрын
Holy crap, these semantics are cool, I'll put up with the additional colons and backwards definitions (name type as opposed to type name) if this is what I get in return!
@clankill3r
@clankill3r 9 жыл бұрын
It's getting more and more interesting each time :) I really hope there is a working prototype within a year or so :D
@gilbertfrausto
@gilbertfrausto 3 жыл бұрын
we are still waiting...
@nintendude794
@nintendude794 2 жыл бұрын
And waiting
@nintendude794
@nintendude794 2 жыл бұрын
A delayed language is eventually good. A bad language is bad forever.
@drygordspellweaver8761
@drygordspellweaver8761 Жыл бұрын
@@nintendude794 i just hope it's not years from now
@georgeokello8620
@georgeokello8620 Жыл бұрын
I think there is a beta version of Jai right now ready to be used.
@iamvfx
@iamvfx 9 жыл бұрын
43:54 This is great.
@mycollegeshirt
@mycollegeshirt 6 жыл бұрын
dude that using.. was amazing.. just drool
@RaZZaK66
@RaZZaK66 5 жыл бұрын
Hey, Jonathan! If this video is about performance and Data-Oriented approach benefits, It'd be cool if you show us some SOA vs AOS benchmark results. I have watched all the video and now I percept SOA as a cool and strange approach to store my data and unfortunately that's it. But I wanna see it as "the best way to store your data", you know Thank you for the video, I hope your language gets more popular, better and faster
@darkengine5931
@darkengine5931 3 жыл бұрын
I just recently optimized a point projector (world space to screenspace) using SoA rep and handwritten SIMD intrinsics. It was the top profiling hotspot for a software rasterizer going at 14-15 FPS. I didn't have a benchmark just testing the point projection in isolation but after the optimization, the full rasterization process (including projecting, rasterizing, and shading) improved to over 35 FPS rendering 2 million triangles/frame. The projection function also disappeared completely as far as hotspots... not even in the top 20 in CodeXL or VTune after I converted to SoA rep and applied SIMD (just SSE2 using 128-bit XMM registers). I suspect it sped up more than the point projector itself to convert to an SoA rep since, while the projection function was the top hotspot, it was only taking around 33% of the time. I hardly expected it to more than double the framerates as it did. It was quite a tedious process to change it though. I didn't have this super cool JAI language -- had to use C++ so it was a fairly intrusive code change. In almost all cases where I've done that and in places where I did have a benchmark testing things in more isolation, I can usually get at least a 2x performance (maybe average 3-4x) over AoS in times where SoA is likely to help (sequential access patterns and possibly some cold fields that could be hoisted out or the ability to use more vertical SIMD without horizontal shuffling).
@ifstatementifstatement2704
@ifstatementifstatement2704 4 ай бұрын
To solve that issue in c++ I just naturally included an attribute by reference. For example class A can have an attribute which is a reference to class B.
@wpwp7507
@wpwp7507 8 жыл бұрын
Hi Jonathon, is there a similar, simplified implementation of composition for the door example in C#?
@iflux8821
@iflux8821 4 ай бұрын
Your videos make me forget about my web developer job 😄
@solhsa
@solhsa 9 жыл бұрын
Also: this language is going to need crazy amount of documentation =)
@bogdanpanchuk296
@bogdanpanchuk296 3 жыл бұрын
but still N times less than C++ needs...
@celeron55
@celeron55 9 жыл бұрын
I'm wondering why Intel hasn't created this language in the past >10 years.
@walter0bz
@walter0bz 9 жыл бұрын
or Sony/Toshiba/IBM. the PS3/CELL processor had a bigger need for this sort of thing. That chip is basically dead because it didn't suit C++.
@kim15742
@kim15742 4 жыл бұрын
Wow, the Witness actually looks like this? Starbound as well. I got to the limits of OOP really fast and was able to switch architecture quite early, thankfully
@SuperIdiotMan00
@SuperIdiotMan00 6 жыл бұрын
36:00 I started humming that song right before you said that.
@Otomega1
@Otomega1 4 жыл бұрын
that is pretty sweet absolutely
@TheFrygar
@TheFrygar 9 жыл бұрын
I really appreciate all the hard work that's going into this. Am I correct in seeing the primary value here being the syntactic sugar? After about 45 minutes or so, I can't help but think that all the performance based ideas are easily achievable in C. All I'm seeing is essentially an Entity struct with a bunch of pointers to data in contiguous arrays. The syntactic sugar of "using" is probably convenient, but that's fairly subjective right? This is all super easy in C, and the SoA stuff is also fairly trivial to set up once you understand it. The talk itself is very useful for those who might be new to these optimization techniques.
@philfort2
@philfort2 9 жыл бұрын
Sure you can do this all in C. But as soon as you change the layout of your data, you'd need to change all the code logic that accesses that data. I think one of the key points of Jon's language proposal is that you can make these changes to data layout without any changes at all to your code logic.
@TheFrygar
@TheFrygar 9 жыл бұрын
Philip Fortier Ya, I definitely see the benefits there - and I'm not suggesting that they're useless. But changing entity.vector.x to entity.hot.vector.x (or whatever) is fairly trivial in most text editors. Again, it's great to see someone bringing these issues to light, I just want to make sure I'm understanding the purpose of these decisions. I'll be very interested to see where the language goes with respect to dependencies and the like.
@jblow888
@jblow888 9 жыл бұрын
Pollen Applebee We're not talking about small beginner programs. Imagine your program is between 300,000 lines and 5,000,000 lines, and consists of thousands of source files. You don't always say entity.vector.x; the variable is called a lot of different names depending on what is going on. A lot of the time you have functions operating on pointers to sub-structs. Maybe you have some macros that don't look anything like entity.vector.x but expand to entity.vector.x. Maybe you have some generated code, so you have to update the generator, which may be nontrivial. You could hope that a refactoring IDE helps you with many of these issues (but it wouldn't handle the macro or generated code case) ... but I have never seen one that works well enough to really use. But why make your language require such a thing to begin with?
@MichaelPankov
@MichaelPankov 9 жыл бұрын
Two levels of indirection might induce way more overhead than occupying cache with big structs. Prefetching of big structs is predictable, but fetching stuff via pointer is not. In other words, AFAIK, CPU won't prefetch a struct behind the pointer. Having nested pointers means prefetching effectively stops. And even if it will, we add another level of indirection meaning cache pressure actually increases. Is it a loss or a gain in performance would depend on relation of sizes of caches and structures, but generally, there's a trade-off presented, not an efficiency silver bullet.
@jblow888
@jblow888 9 жыл бұрын
See my reply above to your previous comment. This structure would actually be a big win for pretty much all games.
@walter0bz
@walter0bz 9 жыл бұрын
what he's achieving is letting you easily change data layout based on profiler feedback, without having to decide the layout upfront.. change how data is split between structures,direct/indirect components etc but the functions that use that data don't need to be refactored at all, just the description. This will be a massive help, IMO.
@xealit
@xealit 6 ай бұрын
AOS-SOA stuff is exactly what the compiler and language should provide for the programmer. C++ pushes out all these 11-17-etc standards, and where's SOA?
@toxicore1190
@toxicore1190 7 жыл бұрын
i want those features now! :C they are so awesome i love it
@drygordspellweaver8761
@drygordspellweaver8761 Жыл бұрын
we still want those features now lol
@cj09beira
@cj09beira 2 ай бұрын
@@drygordspellweaver8761 still waiting 😅
@Vida24322
@Vida24322 9 жыл бұрын
Very good video :D
@thomasoltmann8933
@thomasoltmann8933 9 жыл бұрын
How about using a keyword like 'pull' instead of 'using'? Kind of like 'pull all the contents of that struct into this struct/function/whatever'.
@Otomega1
@Otomega1 5 жыл бұрын
Green conflict with the 'inline' keyword of inline functions
@s4ecki
@s4ecki 4 жыл бұрын
@@Otomega1 are there even inline functuons in jai?
@Otomega1
@Otomega1 4 жыл бұрын
@@s4ecki I dont really know about jai, but i think it can be smart to be consistent with other languages, there are many other keywords more accurate and shorter, pull, spill..
@philtrem
@philtrem 2 жыл бұрын
'using' is much easier to type, 'pull' is kind of a pain to type..
@TheReijoD
@TheReijoD 4 жыл бұрын
I'm not sure C++, as a language, encourages that kind of structuring. C++ is a multi-paradigm language. I think Stroustrup himself has specifically said this. So, it's up to you if you want to implement your Entities like that.
@marcossidoruk8033
@marcossidoruk8033 11 ай бұрын
You didn't understand anything.
@Marius-ir1qn
@Marius-ir1qn 10 ай бұрын
@@marcossidoruk8033 I believe you are the one in the dark here.
@marcossidoruk8033
@marcossidoruk8033 10 ай бұрын
@@Marius-ir1qn you believe. You are also objectively wrong, same as the other guy.
@The1wsx10
@The1wsx10 4 жыл бұрын
if small SOA members are smaller than one byte, wouldn't accessing them be slower? i suppose some bitwise operations aren't too bad
@darkengine5931
@darkengine5931 3 жыл бұрын
Typically not for sequential access. Bitsets can far exceed performance there over an SoA of bools, especially if the loops don't use bitwise AND with variable right-shifts to test for each individual bit unless it has to (ex: skipping 64 bits at a time if they're all unset for a simple example, or using FFZ/FFS for a more complex one). Random access often can be and it's really important to try to distinguish, upfront, whether our data is most frequently going to be accessed in random patterns or sequential ones to determine an optimal representation.
@DanielMircea
@DanielMircea 3 жыл бұрын
Where could I find some benchmarks of this?
@Fnargl99
@Fnargl99 9 жыл бұрын
Jon where do you live stream?
@DusteDdekay
@DusteDdekay 9 жыл бұрын
Suggestion: meta_struct myStruct { hot type name; hot type name; type name; type name; } compiler generates the _hot and _cold structs and generates myStruct with those as members, the members that miss hot/cold will go in hot or cold if the compiler decides there's room for it in the cache of the target ?
@nintendowii2k8
@nintendowii2k8 9 жыл бұрын
Great Video ! Hows The Witness Coming Along ? :)
@SpiritVector
@SpiritVector 2 жыл бұрын
Johnathan, if you don't mind me asking; what is a live pointer in respect to a regular pointer? I wasn't even able to Google it.
@dandymcgee
@dandymcgee 2 жыл бұрын
"live" just means at run-time. I.e. it's not some static compile-time syntactic sugar magic. It's the same as regular pointer.
@jimiscott
@jimiscott Жыл бұрын
This is literally the flyweight pattern...as described in GoF's Design Patterns book published in 1994. The opening line 'Some applications could benefit from using objects throughout their deign, but a naive implementation would be prohibitively expensive.'
@MichaelPohoreski
@MichaelPohoreski 9 жыл бұрын
Jon, if you want to take your programming to the next level (in readability) invest in multi-column alignment. i.e. You would horizontally align all the colons in a sub-section such as mount_parent_id, mount_position, mount_orientation, mount_scale, mount_bone_index. Try it, :-)
@MrHandsy
@MrHandsy 3 жыл бұрын
Would I be able to use this language somehow?
@42f87d89
@42f87d89 9 жыл бұрын
What does it mean for a pointer to be SOA? Is it simply a pointer to something that is SOA?
@DouglasGregoryTO
@DouglasGregoryTO 9 жыл бұрын
I think it means it's a pointer to the array, augmented with an index into the array (and possibly the array's length, if that isn't stored with the array itself). That way you can compute the address of any of the struct's members with only the information contained in the SOA pointer.
@luckylove72
@luckylove72 3 жыл бұрын
6:59 What about custom allocators?
@olivelarouille
@olivelarouille 9 жыл бұрын
Jonathan, very interesting stuff, do you have a public repository so we can look at the code?
@MichaelPankov
@MichaelPankov 9 жыл бұрын
I thought the problem of cache misses would be solved by allocating same objects in pools (like, Vector stores all humans compactly). What do you think of it?
@benjaminpedersen9548
@benjaminpedersen9548 9 жыл бұрын
I don't really know how Vector works in C++, but the idea to reduce cache misses is: Smaller array entries means more entries are loaded into cache on cache misses. Therefore if a function only needs to access one or few members of a struct, the SOA approach (or splitting structs) will result in fewer cache misses.
@MichaelPankov
@MichaelPankov 9 жыл бұрын
Benjamin Pedersen Maybe Vector is not the best example. Laying out structs SOA or AOS is possible in C, the only thing missing is pulling in the name spaces. Regarding fewer cache misses: not sure, since the "united struct" with two pointers will have to be loaded to cache first, and following the pointer will stop prefetching. We actually increase cache pressure by using indirect access.
@jblow888
@jblow888 9 жыл бұрын
Michael Pankov You increase cache pressure in the case where you are doing a lot of computation that can run in parallel with the fetch and/or in code that runs rarely and is expected to be slower. Meanwhile you remove stalls from the tight loops that need to be really fast. For most games this would be a huge win. That said, this is more about providing a toolkit that lets you set up the data layout you want. You certainly don't have to do it the way I mentioned in the demo. As for your claim that laying out structs in SOA is possible in C ... no it isn't. You can take the members that you would have put into a struct and put them into arrays instead, but you can't then treat it as a struct in the language.
@MichaelPankov
@MichaelPankov 9 жыл бұрын
Jonathan Blow Thanks for explanation. Keep up all the good work! :)
@MichaelPankov
@MichaelPankov 9 жыл бұрын
Jonathan Blow By the way: do you have any preliminary benchmarks / timing results? I wonder how much of a win SOA would be. Not being picky, just interested if there are any data you could share :)
@gavinw77
@gavinw77 9 жыл бұрын
hot tight packed data array ...haha
@asdfghyter
@asdfghyter 5 жыл бұрын
33:18 How is this different from the multiple inheritance that Mike Acton described as "just dumb"?
@jblow888
@jblow888 5 жыл бұрын
Uhh, that's not multiple inheritance, it is single inheritance.
@asdfghyter
@asdfghyter 5 жыл бұрын
Yes, but I assumed from the syntax and what you said that it extends to multiple inheritance. Sorry if I misunderstood.
@jblow888
@jblow888 5 жыл бұрын
It doesn't currently, because we only do this conversion for things at memory offset 0, and there can be only one of those. We *could* make it work generally, but I haven't seen a need to do that.
@asdfghyter
@asdfghyter 5 жыл бұрын
Aha, that makes sense. Thank you! Second question: In the video, you said "We didn't express inheritance here". Apart from syntax, what is the difference from actual inheritance? They seem to behave very similarly.
@jblow888
@jblow888 5 жыл бұрын
We don't currently provide any way of shadowing declarations in the thing you are childed from, so the whole OO idea of "subclass the parent but replace some methods" does not apply here. In fact we don't have any such thing as methods, so there is that too.
@user-gw1sh9qc2s
@user-gw1sh9qc2s 6 жыл бұрын
STRUCTOR is a Public Enemy!
@distrologic2925
@distrologic2925 7 жыл бұрын
I want this so bad... Do you think this language will be able to work together with APIs like OpenGL and GLFW?
@jblow888
@jblow888 7 жыл бұрын
I use OpenGL in demos all the time.
@distrologic2925
@distrologic2925 7 жыл бұрын
Jonathan Blow is there even a lot of restriction in that matter? Can you use any languages together if the compiler and linker are supporting both languages? it's kind of a general question out of interest
@jgcooper
@jgcooper 7 жыл бұрын
+Jonathan Blow 1) what is this implemented in? (assembly? c? c++?) 2) could this be done as an extension to C++? (compiler extension?)
@jblow888
@jblow888 7 жыл бұрын
1) C++. 2) No.
@jgcooper
@jgcooper 7 жыл бұрын
+Jonathan Blow what file type does your custom compiler output?
@Jewbender
@Jewbender 3 жыл бұрын
Now we have entt in c++
@firmhand
@firmhand 8 жыл бұрын
Does ARM favor SOA too?
@MaherBaba
@MaherBaba 8 жыл бұрын
+Konstantin Konev Any modern processor that has a cache will favor SOA because what ultimately matters is getting rid of random memory accesses. It doesn't matter what instruction set you will use.
@asdfghyter
@asdfghyter 5 жыл бұрын
Here are the links from the video so you don't have to type them by hand: Noel Llopis, "Data-Oriented Design" gamesfromwithin.com/data-oriented-design Chandler Carruth, "Efficiency with Algorithms, Performance with Data Structures" kzbin.info/www/bejne/nHmxnoWhr917jdU Mike Action, "Data-Oriented Design in C++" kzbin.info/www/bejne/qImTeqeMerudfsU
7 жыл бұрын
what about recursive using? struct A { int: value; } struct B { using A: a; } struct C { using B: b; } ... struct Z { using Y: y; } can I say z.value directly instead of z.y.(...).b.a.value?
@nameguy101
@nameguy101 7 жыл бұрын
Yes
@austecon6818
@austecon6818 5 ай бұрын
This was 8 years ago!?
@supernewuser
@supernewuser 9 жыл бұрын
Ohh so The Witness is going to have Mounts?
@tomwhitcombe7621
@tomwhitcombe7621 2 жыл бұрын
kzbin.info/www/bejne/sJjSoo2qqpZooas
@rakesh4a1
@rakesh4a1 6 жыл бұрын
'vtable' pointer is only the extra overhead that got introduced if you use inheritance over composition.
@youtubesuresuckscock
@youtubesuresuckscock 6 жыл бұрын
Computers aren't getting faster?
@WILLTHECANADIAN
@WILLTHECANADIAN 9 жыл бұрын
I love the ideas behind using and it seems very handy but this vtable nonsense looks real messy.
@SamSarwat90
@SamSarwat90 3 жыл бұрын
Is it only me who thinks that the idea of "using" namespaces is just a bad idea ? I don't know, for me, it just introduces confusion while reading the code. Why would we introduce 2 different ways of refering to a variable.
@CulzeanSwift
@CulzeanSwift 5 жыл бұрын
@28:20 super verbose? wat? super succinct you mean.
@philtrem
@philtrem 2 жыл бұрын
He was being sarcastic.
@PixelOutlaw
@PixelOutlaw 8 жыл бұрын
One thing I like about many dynamically typed languages is that they let me shove all game objects into a container and call update on them all regardless of type. This avoids the mess of derived classes and also interface after interface for composite classes' methods. You just store all objects that need to be together together and apply a universal series of functions that hopefully they all have. Yes it s dangerous for people new to your code. But you know what? It is super clean for a one man development team. I think it is much nicer to have a language that lets me put all kinds enemy classes in a container and simply call update on each one with no type casts and messy case/switch statements.
@localatticus4483
@localatticus4483 8 жыл бұрын
+PixelOutlaw | I like the idea of an implicit interface, which would make what you said entirely possible and extremely simple in a statically typed language that supports it. The idea is as such: You can declare a interface (it can even be private) that represents what you want to operate on. The type checker, when faced with that interface, will simply check if the type in question implements the methods (or whatever the requirement is) of that interface. It needn't do it explicitly, so long as (for example) the `update(delta: float)` method exists (again, or any similar construct in question) then it's able to be treated as that interface implicitly. interface updatable { proc update(delta : float) } proc update(all : []updatable) { /# do things } struct player { /# fields } impl player { proc update(delta : float) { /# update the player } } /# now `player` is implicitly `updatable` That's entirely example code using a similar syntax to a language I'm working on, hopefully that explains the idea well enough.
@PixelOutlaw
@PixelOutlaw 8 жыл бұрын
Best of luck on your language!
@memerichment
@memerichment 8 жыл бұрын
When using a dynamic language, you pay the price at runtime. It might not matter for a small game, but what you suggest is already orders of magnitude slower than the cache problems that Jon has been trying to avoid.
@nameguy101
@nameguy101 7 жыл бұрын
It _does_ matter for a small game. Even a single order of magnitude, as you suggested, will inevitably show up in the user experience.
@PixelOutlaw
@PixelOutlaw 7 жыл бұрын
I'm calling Common Lisp within a SFML C++ project at the moment (via ECL). But it is mostly for assigning instance behaviors at runtime to avoid creating 100 classes for each type of enemy. Users will be able to edit huge sections of my game without ever having to compile source code. And it runs very well having 1000 instances calling updates in real time on an i7 from 3 years ago. I've not even bothered to compile the Lisp functions yet. Would I use it for rendering? Probably not. For user definable behaviors? Works for my needs. This is a 2D bullet hell game, everything is light and fast, the worst being a very fast rectangle to rectangle collision check with 3 early exit conditions. Majority of the time the collision exits early too. As a bonus I can make edits to my bullet pattern scripts and watch the game change without recompiling the damn thing.
@mortenbrodersen8664
@mortenbrodersen8664 8 жыл бұрын
Bjarne Stroustrup (the Danish inventor of C++) does not call C++ an OO language. He calls it a multi-paradigm language. With features to support (among other things) OO.
@kamanashisroy
@kamanashisroy 9 жыл бұрын
Thank you for nice intriguing talk. I wrote down a response to all the problems discussed in a different view. github.com/kamanashisroy/aroop/tree/master/talks/data_oriented_talks
@heyheyhophop
@heyheyhophop 7 жыл бұрын
3:40 or so -- but you DO use dynamic dispatch! As that func over there is virtual :)
@jblow888
@jblow888 7 жыл бұрын
Yeah, when I said that I meant more-complicated stuff like message-passing schemes, but it seems the definition of "dynamic dispatch" includes virtual functions called from base classes, so it was an incorrect utterance.
@heyheyhophop
@heyheyhophop 7 жыл бұрын
Hehe, that's fine, am currently watching it further -- a very nice talk, indeed (was searching for more like Mike Acton's talk on these matters) :)
@heyheyhophop
@heyheyhophop 7 жыл бұрын
www.amazon.com/Generative-Programming-Methods-Tools-Applications/dp/0201309777 is a nice source of terms and insights, if one wants to sound snobby (static VS subtype polymorphism, etc.) :)
@sheldon6822
@sheldon6822 7 жыл бұрын
hey you know this thing with keyword using inside the struct, is much like mixins in ES5-style React classes in JavaScript React.js ecosystem. I know that JAI is not like JavaScript by design, but possibly you should find it out for yourself for educational purposes. P.S. I'm just middle-level game developer (btw working with Python), so maybe my comment is not useful! But my programmer intuition says that React Native project is trying to solve the same problems as the JAI project is about. (defining user interactions and entity representation in data driven way)
@FeuerAurora
@FeuerAurora 9 жыл бұрын
I'd like: modules Group1{ uses TreeNode as TN // get everything from TreeNode under Group1.TN:fn(); uses DoubleLinkedList as DLL // get everything from D.L.L under Group1.DLL:var TN:next DLL:next // both use the same memory cell for their next properties } // "this.property" or "self" refers to scope Group1.TN:property or Group1
@Beefster09
@Beefster09 9 жыл бұрын
Intel should invest in this project. :P So if you can already simulate polymorphic classes, you might as well just put classes in, right? I will admit that classes are kind of overrated, but you can basically implement them by hand... sooo.... Either way, that's cool what you can do with this. I'm just curious as to how it would compare with C++'s implementation of classes. My intuition tells me it might be slower... until you get into SOA shenanigans. That alone probably makes the biggest difference.
@Beefster09
@Beefster09 9 жыл бұрын
I just realized that you can already basically have "normal" classes with compile-time code generation. I forgot that was a thing. Classes are nice because of methods, which are nice in the sense that it's some operations associated with a specific type... but really all a method is is a function that takes the object as an implicit first argument. But really, classes don't have much place in a data-oriented language.
7 жыл бұрын
18:45 I hope that sound is not the way the indexes are
@Dima-ht4rb
@Dima-ht4rb 6 жыл бұрын
It's all fine, but the witness is not that fast of a game, considering how simple it is and there are unreal engine 4 in production, which is written with all those slow things, all in-game object are heap allocated and their renderer doesn't look that slow.
@jblow888
@jblow888 6 жыл бұрын
This reads like a nonsense comment to me.
@MarkoMikulicic
@MarkoMikulicic 2 жыл бұрын
"abusing using"
@epigeios
@epigeios 8 жыл бұрын
Doesn't SOA vs AOS depend on use? Like if you iterate through the struct in order..... Ha, nevermind. That never happens.
@trisinogy
@trisinogy 4 жыл бұрын
So, what about the performance? Data-oriented programming is all about performance...
@dbporter
@dbporter 4 жыл бұрын
I can't watch this, it's using emacs
Q&A after Data-Oriented Demo
45:22
Jonathan Blow
Рет қаралды 16 М.
ISSEI funny story😂😂😂Strange World | Magic Lips💋
00:36
ISSEI / いっせい
Рет қаралды 183 МЛН
1 класс vs 11 класс (неаккуратность)
01:00
БЕРТ
Рет қаралды 1,9 МЛН
Why? 😭 #shorts by Leisi Crazy
00:16
Leisi Crazy
Рет қаралды 44 МЛН
8 Design Patterns EVERY Developer Should Know
9:47
NeetCode
Рет қаралды 987 М.
Ideas about a new programming language for games.
1:55:24
Jonathan Blow
Рет қаралды 437 М.
Every single feature of C# in 10 minutes
9:50
Train To Code
Рет қаралды 79 М.
Rant: Entity systems and the Rust borrow checker ... or something.
1:01:51
Time To Switch To Linux?
10:55
Britec09
Рет қаралды 11 М.
why are switch statements so HECKIN fast?
11:03
Low Level Learning
Рет қаралды 369 М.
I Tried JAI, Can It Replace C++?! (Programming Language)
21:05
how Google writes gorgeous C++
7:40
Low Level Learning
Рет қаралды 751 М.
Abstraction Layers in Programming - Jonathan Blow
5:36
gamedev cuts
Рет қаралды 18 М.
C++ Crash Course: Data Oriented Design
13:12
CoffeeBeforeArch
Рет қаралды 23 М.
Я просто в шоке от этого…!!!😰😰😰
0:54
Dynamike 1v3 Challenge 💣
0:38
Toodyxz
Рет қаралды 5 МЛН
Caseoh VS Sonic & Aphmau | Minecraft & Sonic
0:12
Mischief time
Рет қаралды 10 МЛН
CAN YOU FIGURE THIS OUT?! 🤯 #shorts *10000 IQ CHALLENGE!*
0:10