Data-Oriented Demo: SOA, composition

Ойындар

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?

Пікірлер: 187

  • @bus
    @bus6 жыл бұрын

    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 KZread

  • @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.

  • @jonkrieger5271
    @jonkrieger52719 жыл бұрын

    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++" kzread.info/dash/bejne/pIxkq9aPdbnQeMY.html

  • @anonymous4711_

    @anonymous4711_

    4 жыл бұрын

    @@JustMe-fl1db the real MVP right here

  • @AlanBalls
    @AlanBalls9 жыл бұрын

    You can do this in C++! **posts nightmare code**

  • @Kavukamari

    @Kavukamari

    7 жыл бұрын

    thanks, satan!

  • @zemlidrakona2915

    @zemlidrakona2915

    4 жыл бұрын

    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

    4 жыл бұрын

    @@zemlidrakona2915 You forgot option (c): a joke by op

  • @miko007

    @miko007

    4 жыл бұрын

    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

  • @notsoren665
    @notsoren6653 жыл бұрын

    Jonathan has had the same character development as Saitama. As he becomes a better programmer he loses more hair.

  • @Dengakuman22
    @Dengakuman229 жыл бұрын

    Ok, door_test_4 was like: Why doesn't this exist already? Keep up the good work! This is starting to look awesome.

  • @walter0bz
    @walter0bz9 жыл бұрын

    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

    2 жыл бұрын

    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.

  • @JoshStefanski
    @JoshStefanski9 жыл бұрын

    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.

  • @majidarifs
    @majidarifs9 жыл бұрын

    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?

  • @thund7963
    @thund79639 жыл бұрын

    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.

  • @rtvdenys
    @rtvdenys5 ай бұрын

    "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.

  • @Maldito011316
    @Maldito0113169 жыл бұрын

    Great video, Jonathan!! I'm enjoying it as I watch in parts. Keep it up! :D

  • @HiAdrian
    @HiAdrian9 жыл бұрын

    Coincidentally I was looking you up yesterday, wondering if anything new on the language had surfaced on the web. This is a nice surprise.

  • @DouglasGregoryTO
    @DouglasGregoryTO9 жыл бұрын

    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.

  • @ANT-jm4qx
    @ANT-jm4qxАй бұрын

    RIP in peace John Blow's majestic mane

  • @GingerGames
    @GingerGames9 жыл бұрын

    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?

  • @solhsa
    @solhsa9 жыл бұрын

    I pondered whether "embed" would be better than "using" inside struct.. or "collapse", but after some thought I think using "using" everywhere is better.

  • @TheXello
    @TheXello5 жыл бұрын

    I am excited to use this language in my own projects.

  • @kazriko
    @kazriko6 жыл бұрын

    You answered my question on a prior video before I posed it, nice.

  • @taylorius
    @taylorius9 жыл бұрын

    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.

  • @digitalconsciousness
    @digitalconsciousness3 жыл бұрын

    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.

  • @_profan
    @_profan9 жыл бұрын

    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

    7 жыл бұрын

    A similar thing for Julia: github.com/simonster/StructsOfArrays.jl.

  • @iamvfx
    @iamvfx9 жыл бұрын

    43:54 This is great.

  • @mycollegeshirt
    @mycollegeshirt6 жыл бұрын

    dude that using.. was amazing.. just drool

  • @TECHN01200
    @TECHN01200 Жыл бұрын

    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!

  • @Vesuvian
    @Vesuvian9 жыл бұрын

    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

    9 ай бұрын

    a long time apparently 😭😭😭

  • @RaZZaK66
    @RaZZaK665 жыл бұрын

    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).

  • @SuperIdiotMan00
    @SuperIdiotMan006 жыл бұрын

    36:00 I started humming that song right before you said that.

  • @wpwp7507
    @wpwp75078 жыл бұрын

    Hi Jonathon, is there a similar, simplified implementation of composition for the door example in C#?

  • @Otomega1
    @Otomega14 жыл бұрын

    that is pretty sweet absolutely

  • @clankill3r
    @clankill3r9 жыл бұрын

    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.

  • @iflux8821
    @iflux88216 ай бұрын

    Your videos make me forget about my web developer job 😄

  • @kim15742
    @kim157424 жыл бұрын

    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

  • @xealit
    @xealit9 ай бұрын

    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?

  • @Vida24322
    @Vida243229 жыл бұрын

    Very good video :D

  • @DusteDdekay
    @DusteDdekay9 жыл бұрын

    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 ?

  • @TheFrygar
    @TheFrygar9 жыл бұрын

    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
    @MichaelPankov9 жыл бұрын

    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.

  • @celeron55
    @celeron559 жыл бұрын

    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++.

  • @jimiscott
    @jimiscott2 жыл бұрын

    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.'

  • @ifstatementifstatement2704
    @ifstatementifstatement27047 ай бұрын

    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.

  • @JiggyJones0

    @JiggyJones0

    21 күн бұрын

    That's how composition works

  • @DanielMircea
    @DanielMircea3 жыл бұрын

    Where could I find some benchmarks of this?

  • @Fnargl99
    @Fnargl999 жыл бұрын

    Jon where do you live stream?

  • @toxicore1190
    @toxicore11908 жыл бұрын

    i want those features now! :C they are so awesome i love it

  • @drygordspellweaver8761

    @drygordspellweaver8761

    Жыл бұрын

    we still want those features now lol

  • @cj09beira

    @cj09beira

    4 ай бұрын

    @@drygordspellweaver8761 still waiting 😅

  • @solhsa
    @solhsa9 жыл бұрын

    Also: this language is going to need crazy amount of documentation =)

  • @bogdanpanchuk296

    @bogdanpanchuk296

    3 жыл бұрын

    but still N times less than C++ needs...

  • @The1wsx10
    @The1wsx104 жыл бұрын

    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.

  • @olivelarouille
    @olivelarouille9 жыл бұрын

    Jonathan, very interesting stuff, do you have a public repository so we can look at the code?

  • @MrHandsy
    @MrHandsy3 жыл бұрын

    Would I be able to use this language somehow?

  • @thomasoltmann8933
    @thomasoltmann89339 жыл бұрын

    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

    6 жыл бұрын

    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

    3 жыл бұрын

    'using' is much easier to type, 'pull' is kind of a pain to type..

  • @luckylove72
    @luckylove724 жыл бұрын

    6:59 What about custom allocators?

  • @romanzkv4
    @romanzkv4Ай бұрын

    Very interesting

  • @MichaelPohoreski
    @MichaelPohoreski9 жыл бұрын

    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, :-)

  • @SpiritVector
    @SpiritVector2 жыл бұрын

    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.

  • @42f87d89
    @42f87d899 жыл бұрын

    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.

  • @nintendowii2k8
    @nintendowii2k89 жыл бұрын

    Great Video ! Hows The Witness Coming Along ? :)

  • @rakesh4a1
    @rakesh4a16 жыл бұрын

    'vtable' pointer is only the extra overhead that got introduced if you use inheritance over composition.

  • @TheReijoD
    @TheReijoD4 жыл бұрын

    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

    Жыл бұрын

    You didn't understand anything.

  • @Marius-ir1qn

    @Marius-ir1qn

    Жыл бұрын

    @@marcossidoruk8033 I believe you are the one in the dark here.

  • @marcossidoruk8033

    @marcossidoruk8033

    Жыл бұрын

    @@Marius-ir1qn you believe. You are also objectively wrong, same as the other guy.

  • @gavinw77
    @gavinw779 жыл бұрын

    hot tight packed data array ...haha

  • @MichaelPankov
    @MichaelPankov9 жыл бұрын

    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 :)

  • @user-gw1sh9qc2s
    @user-gw1sh9qc2s7 жыл бұрын

    STRUCTOR is a Public Enemy!

  • @Jewbender
    @Jewbender3 жыл бұрын

    Now we have entt in c++

  • @firmhand
    @firmhand8 жыл бұрын

    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.

  • 8 жыл бұрын

    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

  • @asdfghyter
    @asdfghyter6 жыл бұрын

    33:18 How is this different from the multiple inheritance that Mike Acton described as "just dumb"?

  • @jblow888

    @jblow888

    6 жыл бұрын

    Uhh, that's not multiple inheritance, it is single inheritance.

  • @asdfghyter

    @asdfghyter

    6 жыл бұрын

    Yes, but I assumed from the syntax and what you said that it extends to multiple inheritance. Sorry if I misunderstood.

  • @jblow888

    @jblow888

    6 жыл бұрын

    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

    6 жыл бұрын

    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

    6 жыл бұрын

    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.

  • @supernewuser
    @supernewuser9 жыл бұрын

    Ohh so The Witness is going to have Mounts?

  • @asdfghyter
    @asdfghyter6 жыл бұрын

    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" kzread.info/dash/bejne/mHyCz7Skqtuuh9Y.html Mike Action, "Data-Oriented Design in C++" kzread.info/dash/bejne/pIxkq9aPdbnQeMY.html

  • @austecon6818
    @austecon68187 ай бұрын

    This was 8 years ago!?

  • @distrologic2925
    @distrologic29257 жыл бұрын

    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?

  • @tomwhitcombe7621
    @tomwhitcombe76212 жыл бұрын

    kzread.info/dash/bejne/rJuj07ytpZSbm6w.html

  • @romanzkv4
    @romanzkv4Ай бұрын

    in second though, you are totaly complicating this thing, you dont need to traverse your entities multiple times, if you need speed, then you add "collecg geometry" to your entities, you make a pass, and you collect all the geometry data you need for rendering, this way you still pay only once for cache misses, but you end up with a buffer that is compatible for the gpu, then you render this buffer as many times as you need. and this way you dont need all this low level of control of your memory layout. - so you still have simple inheritence which is useful, and you have your speed.

  • @youtubesuresuckscock
    @youtubesuresuckscock6 жыл бұрын

    Computers aren't getting faster?

  • @PixelOutlaw
    @PixelOutlaw8 жыл бұрын

    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.

  • @WILLTHECANADIAN
    @WILLTHECANADIAN9 жыл бұрын

    I love the ideas behind using and it seems very handy but this vtable nonsense looks real messy.

  • @mortenbrodersen8664
    @mortenbrodersen86648 жыл бұрын

    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.

  • @SamSarwat90
    @SamSarwat903 жыл бұрын

    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.

  • 7 жыл бұрын

    18:45 I hope that sound is not the way the indexes are

  • @CulzeanSwift
    @CulzeanSwift5 жыл бұрын

    @ 28:20 super verbose? wat? super succinct you mean.

  • @philtrem

    @philtrem

    3 жыл бұрын

    He was being sarcastic.

  • @sheldon6822
    @sheldon68227 жыл бұрын

    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)

  • @heyheyhophop
    @heyheyhophop7 жыл бұрын

    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.) :)

  • @FeuerAurora
    @FeuerAurora9 жыл бұрын

    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

  • @epigeios
    @epigeios8 жыл бұрын

    Doesn't SOA vs AOS depend on use? Like if you iterate through the struct in order..... Ha, nevermind. That never happens.

  • @kamanashisroy
    @kamanashisroy9 жыл бұрын

    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

  • @MarkoMikulicic
    @MarkoMikulicic2 жыл бұрын

    "abusing using"

  • @Beefster09
    @Beefster099 жыл бұрын

    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.

  • @Dima-ht4rb
    @Dima-ht4rb7 жыл бұрын

    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

    7 жыл бұрын

    This reads like a nonsense comment to me.

  • @trisinogy
    @trisinogy4 жыл бұрын

    So, what about the performance? Data-oriented programming is all about performance...

  • @davidporterrealestate
    @davidporterrealestate4 жыл бұрын

    I can't watch this, it's using emacs

Келесі