Earlier quoted context omitted.
No, the main gripe of this article is data locality, not vectorization. Those two are completely orthogonal and complementary: you can have data locality without vectorization and vectorization without data locality, and both bring performance improvements. But vectorization bring a constant speedup (from x2 to maybe x16 depending on the ISA of the processor), but data locality can improve performance much more becau…
Struct of arrays layouts does put you in a good position to apply vectorization techniques though. The article is rather more about columnar vs row formats for program entities than it is about locality generally. Columnar databases often use vectorized evaluation strategies because it's low-hanging fruit.
The compiler will optimize that away
111–120 of 329 posts
Re: The compiler will optimize that away
#112Re: The compiler will optimize that away
#113Good article. My own thinking when coding performance is also towards data oriented approaches. For example Bevy in Rust. If stuff needs to be fast, it needs to be in cache. To do that, have everything nicely packed so you only ask for a chunk as often as you need. Then when you need it, it's already there. Thing about old fashioned OO is it's often fine enough for your run-of-the-mill CRUD app. If you look at the la…
> If you imagine a game that has characters, relationships, items, spells, and so on, it's often not that easy to model as encapsulated objects. I...disagree. ECS definitely has efficiency advantages for games in terms of support performant implementations, which for games is often overwhelmingly critical, but there’s well understand OO ways to address the modelling issue tou raise. > Does each character have a list…
Re: The compiler will optimize that away
#114Summary: the computer has changed -- memory latency measured in CPU cycles has grown a lot. So we should not be using traditional struct/class-like programming model, where we put all properties of an object next to each other. Instead, we should be using game-style "data oriented programming" a.k.a. "column databases" for a much higher performance. However, most modern languages (C, C++, Python, Java, etc..) are not…
Re: The compiler will optimize that away
#115Good article. My own thinking when coding performance is also towards data oriented approaches. For example Bevy in Rust. If stuff needs to be fast, it needs to be in cache. To do that, have everything nicely packed so you only ask for a chunk as often as you need. Then when you need it, it's already there. Thing about old fashioned OO is it's often fine enough for your run-of-the-mill CRUD app. If you look at the la…
OTOH, this is where I can see the biggest benefits from building a language/system around the article’s approach. You’d really like to execute a lot of the logic on the DB (or some other distributed system) which needs to be deeply integrated with the DB to be as convenient and expressive as pulling the data and operating locally.
Re: The compiler will optimize that away
#116Earlier quoted context omitted.
What is an "escaping aggregate"?; this term has 80 hits on Google , none of which seem to be related to programming. Looking it up “aggregate” is a C++ term for which the standard indeed does explicitly allow various optimizations and guarantees about data layout are weakened; this is not the case with C arrays. Do you have any practical evidence to C compilers altering the data layout of an array in any way?
GP’s comment is referring to Scalar Replacement of Aggregates on the one hand. This is an optimization where by the compiler will, for a function with a Struct argument, only pass in a pointer to / copy of the actual element of the struct used inside a function. Hence the name, the compiler is replacing the aggregate struct by one or more of the individual values it contains. The reference to non-escaping aggregates,…
Re: The compiler will optimize that away
#117There’s a nice introduction to a data-oriented approach in here, but it’s buried in some junk. E.g., I don’t think a lot of developers believe compilers are magic optimizers. And programming languages, including the ones referenced, have changed quite a bit over the last 20 years. A strong enough case for general data-oriented features would cause at least some of them to support it. Also, a great amount of code shou…
Re: The compiler will optimize that away
#118Earlier quoted context omitted.
That what I refer to as the "Turing complete" argument. Yes, you can definitely do all of those. But almost no one does - and those that do, usually silo themselves from the ecosystem. Yes, if you like Java, you can definitely implement a Java compiler/interpreter in C and get everything you like about Java using C. But no one does. Thanks for the reference, I'll read about annotation processors later tonight.
I appreciate the discussion, but I believe you're arguing in bad faith. > Yes, you can definitely do all of those. But almost no one does That's what you say. What is this based on, considering that until a few hours ago you didn't even know that Java has this built-in code generation facility? When I search for "entity component sytem java", the first hit is this project: https://github.com/Rubentxu/Entitas-Java whi…
I wasn't aware it is now an integrated part of the JDK, but it doesn't change much; I've used ANTLR decades ago (and YACC even more decades ago) which is ... essentially the same thing, except Java has now standardized and simplified it so that you don't need to fiddle with your Ant or Maven or Makefile.
> Sure, it's probably not as widely used as other frameworks in other languages.
I've been doing professional work for over 30 years now, so I think I have some perspective, which may of course be different than yours. Code generators and processors have always had their niches, but that's what they are - niches - and they are quite small.
People used to use YACC, or ANTLR or Bison or Lemon or whatever your favorite parsing tool is. That's because they save an enormous amount of work in most use cases where they are applied. But they also come with great costs: Hard to debug when things go wrong, but most importantly - inflexible. GCC and many, many other projects move off parser generators at some point in their life for flexibility reasons.
Qt has MOC, which was essential in older C++ and is now IIRC optional because modern C++ has mostly caught up. It is widely hated among Qt users, though it did offer significant advantages. But I'm not aware of any project that used MOC except to interface with Qt - the boundary is always evident.
> You have not shown this. And if you mean that your C macro implementations do this -- fine. But you still seem to find them useful enough to keep using them?
How could I "show" this? It is obviously predicated on the projects I've been involved with, which - I noted - have not been Java in the last ten years. It's not like it's something that can be "shown", except in some statistical sense, the validity of which we will argue forever.
And yes, people shy away from macro heavy C code (whenever J source code or A source code gets posted on HN, people are less than happy, e.g. https://news.ycombinator.com/item?id=8533843 ; the whole J system looks like that ).
I use macro heavy code only when I don't have to share it with others, for that reason.
> But using a very simple code generator for a very simple problem is not the same thing.
Well, perhaps we're not thinking of the same level of simple - e.g. c++ template meta programming, which I first used in 1995 is built in, and (literally) turing complete, so it can do anything, but is far from "simple" - not to actually write, not to use, and definitely not to debug.
What I had in mind was things like https://github.com/Hirrolot/poica - It uses C macros to do incredible magic. All it needs is one #include and it gives C introspection, oop and a few other things. Is it simple? I wouldn't say that. But more importantly, is it C ? I wouldn't say that, and so does the guy who made it. It can be used in a C program, yes. It can e.g. go further and define comparators for you so you can use qsort() on the new types it helps you define. But it's not really C because when you try to integrate it with an existing C codebase, you'll find that you keep having to translate things at every boundary - which is quite likely to happen with a Java SoA library.
I think my point is that languages in common use (Java, C, C#, ...), despite offering the facilities to locally solve the issues described in the original article (locality of reference mostly), they do not practically allow these solutions to become widespread or common because they are not part of the core, and as a result you lose all benefits on library boundaries.
Re: The compiler will optimize that away
#119Earlier quoted context omitted.
> Somehow over the years I've found that the animals/cars analogies given in OO tutorials are one of the few places that fit well with the model. Yes, and I've never actually needed to implement a cat or a cow in any project :) The other thing for which OO works much better than plain data is GUIs - and I think it is not a coincidence that OO popularity exploded together with the the coming-of-age of GUIs. The other…
> The other canonical example of OO - "Shapes" - doesn't actually work well at all. Shapes work quite well with OO if you design the heirarchy right using is-a relationships, the typically cited problem involves applying is-a relationships which apply to immutable geometric concept of shapes to mutable representations whose mutation contracts don’t support the is-a relationship of the immutable shapes. This would act…
Everything OOP works well in Smalltalk (and most of it does in Python), but you pay dearly for that in efficiency - which is what this article as about.
Re: The compiler will optimize that away
#120Earlier quoted context omitted.
> The other canonical example of OO - "Shapes" - doesn't actually work well at all. Shapes work quite well with OO if you design the heirarchy right using is-a relationships, the typically cited problem involves applying is-a relationships which apply to immutable geometric concept of shapes to mutable representations whose mutation contracts don’t support the is-a relationship of the immutable shapes. This would act…
I should have added "in C / C++ / C#". Everything OOP works well in Smalltalk (and most of it does in Python), but you pay dearly for that in efficiency - which is what this article as about.
The only part of my response that would have effected was the aside about Smalltalk-style “become”, not the main point about the problem being one of constructing an inheritance heirarchy based on relations of immutable entity and using it for mutable entities with mutation contracts that don’t observe the same is-a heirarchy.