Somewhat related: I believe Jonathan Blow's currently unreleased Jai programming language is meant to do some interesting new things in this area, enabling (or rather, greatly simplifying) automatic transformations relating to memory layouts.
It has already been a major research focus the past 50 years or so. We have made great strides, yes, but we are still very far from where it needs to be to compete with lower level languages.
The compiler is a tool, you can set the field to help it do its job, but it's no magic wand, it cannot think and understand your application: only you can do that.
Thanks, I'd not seen that before, very neat. [0] I thought it was just going to be an option to be row-major or column-major, but no: Instead of storing a single list of items, MultiArrayList stores separate lists for each field of the struct.
Could this be done in C++, perhaps with template metaprogramming?
> The compiler is a tool, you can set the field to help it do its job, but it's no magic wand
A paraphrasing of a familiar Mike Acton quote. Fittingly it was mentioned in a blog post that mentions the Jai language. [1][2] I find it frustratingly insubstantial. Given we all presumably accept Rice's theorem and how it applies to compiler optimization, it's a rather empty quip, especially considering we're discussing future possibilities.
Today's compilers are capable of some impressive optimizations. It doesn't do to just dismiss the idea that tomorrow's compilers might be able to do significantly more with memory layouts.
Consider if, decades ago, a sceptic of optimizing compilers had said: Compilers are useful tools, but they are not magic wands, and cannot achieve highly optimized instruction-selection and register-allocation. It cannot think and understand your application: only you can do that. The baseless suggestion that efficient register-allocation is impossible in the absence of a strong AI, would seem laughable today.
> it cannot think and understand your application: only you can do that.
Today's compilers are not strong AIs, sure enough, but that doesn't speak to the point here.
Optimizers and static-analysis tools are capable of reasoning about program behaviour. Again, you haven't justified dismissing the suggestion that future optimizing compilers might be much more sophisticated at this kind of transformation. Perhaps I'm an optimist for arguing for the sufficiently smart compiler, but it doesn't strike me as beyond the realm of possibility.
Perhaps the closer answer is to adjust (or indeed replace) our languages to be more amenable to memory layout transformations than C/C++. This would presumably be comparatively easy to implement.
[0] https://ziglang.org/documentation/master/std/#std;MultiArray...
[1] https://blog.royalsloth.eu/posts/the-compiler-will-optimize-...
I'm not aware of anything in his language that would make it easy for the compiler to automatically decide a better memory layout.
It's rather the opposite: preventing the compiler from doing such things.
For example, struct layout is always the order that you declare. There's no "feature" in his language that would re-order struct fields to minimize padding or anything like that.
gnuvince mentioned that the Zig language seems to be making inroads here too: https://ziglang.org/documentation/master/std/#std;MultiArray...
> this is all userland code
I imagine you meant library code here?
However, if your code has random access, there's no point in using arrays of structures. The compiler would have to modify the order of execution of instructions inside your method to take advantage of how the data is laid out.
However your reply does not answer the question.
Do you know of any CPU that has specific instructions to handle cache? How can you be sure that you are gaming cache lines when even the mnemonics are mostly virtualised through all the pipeline and jump/memory pattern predictions?
It often requires UB to optimize well, which many people aren't into letting it do.
Could you link an example of compilers accommodating these optimizations?
https://llvm.org/docs/Vectorizers.html#slp-vectorizer
Cache precedence and cache line optimisations are black magic, either you know specifically the cpu that you are targeting, or rely on hopium techniques like cache oblivious algorithms that try to reap some benefits.
The baseline is to measure, always, before and after optimisation(s). These "Data oriented design" approaches are very hard to measure and change rapidly because they have a profound impact on a codebase, rarely ever change "just one thing" and they err to the less intuitive and less readable side.