Data-Oriented Demo: SOA, composition

Поділитися
Вставка
  • Опубліковано 12 вер 2024
  • 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
    @bus 6 років тому +131

    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 років тому +27

      SOA = Structures of Arrays.

    • @rustydagger456
      @rustydagger456 5 років тому +9

      ^ ^ ^ I'd also like to know where, I'm curious about the reason/ing

    • @0xCAFEF00D
      @0xCAFEF00D 5 років тому +1

      I'm guessing it's some twitch stream.

    • @needlessoptions
      @needlessoptions 4 роки тому +13

      He's demoed it now bois, it's one of his most recent videos here on UA-cam

    • @PhyloGenesis
      @PhyloGenesis 2 роки тому +3

      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.

  • @notsoren665
    @notsoren665 3 роки тому +22

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

  • @jonkrieger5271
    @jonkrieger5271 9 років тому +46

    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 років тому +4

      Mike Acton, "Data-Oriented Design and C++"
      ua-cam.com/video/rX0ItVEVjHc/v-deo.html

    • @anonymous4711_
      @anonymous4711_ 4 роки тому +1

      @@JustMe-fl1db the real MVP right here

  • @walter0bz
    @walter0bz 9 років тому +52

    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.

  • @thund7963
    @thund7963 9 років тому +11

    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.

  • @DouglasGregoryTO
    @DouglasGregoryTO 9 років тому +11

    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 років тому +1

      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 років тому +3

      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.

  • @degenerate_triangle
    @degenerate_triangle 9 років тому +11

    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 2 роки тому +1

      agreed. it can be weird reading entity.pos.x and somewhere else entity.x when they both access the same member.

  • @taylorius
    @taylorius 9 років тому +17

    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 років тому +8

      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 років тому +3

      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 років тому +5

      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.

  • @rtvdenys
    @rtvdenys 7 місяців тому

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

  • @GingerGames
    @GingerGames 9 років тому +13

    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?

  • @majidarifs
    @majidarifs 9 років тому +7

    Love the videos, first saw you on a documentary about Indie Games. Have been a fan ever since. Very excited about the new language :)

  • @_profan
    @_profan 9 років тому +10

    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 років тому +12

      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 років тому +4

      Just found the implementation, appreciate the info! These things are easy to miss in small communities.

    • @kcarlsson89
      @kcarlsson89 7 років тому +2

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

  • @digitalconsciousness
    @digitalconsciousness 3 роки тому +13

    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.

  • @AlanBalls
    @AlanBalls 9 років тому +202

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

    • @Kavukamari
      @Kavukamari 7 років тому +25

      thanks, satan!

    • @zemlidrakona2915
      @zemlidrakona2915 4 роки тому +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 роки тому +28

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

    • @miko007
      @miko007 4 роки тому +9

      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 роки тому +1

      @@zemlidrakona2915 Nightmare code is when one has to read code written by others. :o

  • @Dengakuman22
    @Dengakuman22 9 років тому +2

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

  • @solhsa
    @solhsa 9 років тому +6

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

  • @HiAdrian
    @HiAdrian 9 років тому +1

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

  • @Vesuvian
    @Vesuvian 9 років тому +6

    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 10 місяців тому

      a long time apparently 😭😭😭

  • @RaZZaK66
    @RaZZaK66 6 років тому +6

    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 роки тому +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).

  • @TECHN01200
    @TECHN01200 Рік тому +1

    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!

  • @celeron55
    @celeron55 9 років тому +25

    I'm wondering why Intel hasn't created this language in the past >10 years.

    • @walter0bz
      @walter0bz 9 років тому +22

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

  • @MichaelPankov
    @MichaelPankov 9 років тому +2

    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 років тому +2

      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.

  • @TheFrygar
    @TheFrygar 9 років тому +1

    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 років тому +6

      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 років тому +1

      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 років тому +10

      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?

  • @xealit
    @xealit 10 місяців тому +1

    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?

  • @iamvfx
    @iamvfx 9 років тому +12

    43:54 This is great.

  • @mycollegeshirt
    @mycollegeshirt 7 років тому +7

    dude that using.. was amazing.. just drool

  • @clankill3r
    @clankill3r 9 років тому +2

    It's getting more and more interesting each time :)
    I really hope there is a working prototype within a year or so :D

  • @ANT-jm4qx
    @ANT-jm4qx 2 місяці тому +1

    RIP in peace John Blow's majestic mane

  • @Maldito011316
    @Maldito011316 9 років тому

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

  • @TheReijoD
    @TheReijoD 4 роки тому +2

    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.

  • @asdfghyter
    @asdfghyter 6 років тому +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"
    ua-cam.com/video/fHNmRkzxHWs/v-deo.html
    Mike Action, "Data-Oriented Design in C++"
    ua-cam.com/video/rX0ItVEVjHc/v-deo.html

  • @solhsa
    @solhsa 9 років тому +37

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

  • @jimiscott
    @jimiscott 2 роки тому +2

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

  • @thomasoltmann8933
    @thomasoltmann8933 9 років тому +11

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

  • @ifstatementifstatement2704
    @ifstatementifstatement2704 8 місяців тому

    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 2 місяці тому

      That's how composition works

  • @kazriko
    @kazriko 6 років тому

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

  • @olivelarouille
    @olivelarouille 9 років тому +4

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

  • @MichaelPohoreski
    @MichaelPohoreski 9 років тому +1

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

  • @iflux8821
    @iflux8821 8 місяців тому

    Your videos make me forget about my web developer job 😄

  • @MichaelPankov
    @MichaelPankov 9 років тому +7

    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 років тому +2

      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 років тому +17

      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 років тому +1

      Jonathan Blow Thanks for explanation.
      Keep up all the good work! :)

    • @MichaelPankov
      @MichaelPankov 9 років тому +1

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

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

  • @The1wsx10
    @The1wsx10 4 роки тому +1

    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.

  • @TheXello
    @TheXello 6 років тому

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

  • @SuperIdiotMan00
    @SuperIdiotMan00 6 років тому

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

  • @wpwp7507
    @wpwp7507 8 років тому

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

  • @nintendowii2k8
    @nintendowii2k8 9 років тому +2

    Great Video ! Hows The Witness Coming Along ? :)

  • @MrHandsy
    @MrHandsy 3 роки тому +1

    Would I be able to use this language somehow?

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

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

  •  8 років тому +3

    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?

  • @toxicore1190
    @toxicore1190 8 років тому +3

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

  • @Otomega1
    @Otomega1 4 роки тому

    that is pretty sweet absolutely

  • @distrologic2925
    @distrologic2925 7 років тому +1

    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 років тому +4

      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 років тому +1

      +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

      1) C++.
      2) No.

    • @jgcooper
      @jgcooper 7 років тому

      +Jonathan Blow
      what file type does your custom compiler output?

  • @DanielMircea
    @DanielMircea 3 роки тому

    Where could I find some benchmarks of this?

  • @Jewbender
    @Jewbender 3 роки тому +1

    Now we have entt in c++

  • @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 років тому +1

      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.

  • @rakesh4a1
    @rakesh4a1 6 років тому +1

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

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

  • @romanzkv4
    @romanzkv4 3 місяці тому

    Very interesting

  • @luckylove72
    @luckylove72 4 роки тому

    6:59 What about custom allocators?

  • @Fnargl99
    @Fnargl99 9 років тому

    Jon where do you live stream?

  • @austecon6818
    @austecon6818 8 місяців тому

    This was 8 years ago!?

  • @tomwhitcombe7621
    @tomwhitcombe7621 2 роки тому +2

    ua-cam.com/video/zgoqZtu15kI/v-deo.html

  • @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 років тому +1

      +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 років тому +6

      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.

  • @Vida24322
    @Vida24322 9 років тому

    Very good video :D

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

  • @supernewuser
    @supernewuser 9 років тому

    Ohh so The Witness is going to have Mounts?

  • @asdfghyter
    @asdfghyter 6 років тому

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

    • @jblow888
      @jblow888  6 років тому +1

      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 років тому +1

      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 років тому +1

      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 років тому +4

      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 7 років тому

    STRUCTOR is a Public Enemy!

  • @youtubesuresuckscock
    @youtubesuresuckscock 6 років тому

    Computers aren't getting faster?

  • @gavinw77
    @gavinw77 9 років тому

    hot tight packed data array ...haha

  • @heyheyhophop
    @heyheyhophop 7 років тому +3

    3:40 or so -- but you DO use dynamic dispatch! As that func over there is virtual :)

    • @jblow888
      @jblow888  7 років тому +6

      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 років тому +3

      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 років тому +1

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

  • @firmhand
    @firmhand 9 років тому

    Does ARM favor SOA too?

    • @MaherBaba
      @MaherBaba 8 років тому +5

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

  • @WILLTHECANADIAN
    @WILLTHECANADIAN 9 років тому

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

  • @CulzeanSwift
    @CulzeanSwift 5 років тому +1

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

    • @philtrem
      @philtrem 3 роки тому

      He was being sarcastic.

  • @sheldon6822
    @sheldon6822 8 років тому

    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)

  • @Dima-ht4rb
    @Dima-ht4rb 7 років тому +2

    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 років тому +8

      This reads like a nonsense comment to me.

  •  7 років тому

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

  • @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 років тому +1

      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.

  • @romanzkv4
    @romanzkv4 3 місяці тому

    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.

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

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

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

  • @MarkoMikulicic
    @MarkoMikulicic 2 роки тому

    "abusing using"

  • @trisinogy
    @trisinogy 4 роки тому

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

  • @davidporterrealestate
    @davidporterrealestate 4 роки тому +1

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