TE
TechEcho
AccueilTop 24hRécentsMeilleursQuestionsPrésentationsEmplois
GitHubTwitter
Accueil

TechEcho

Une plateforme d'actualités technologiques construite avec Next.js, fournissant des nouvelles et discussions technologiques mondiales.

GitHubTwitter

Accueil

AccueilRécentsMeilleursQuestionsPrésentationsEmplois

Ressources

HackerNews APIHackerNews OriginalNext.js

© 2025 TechEcho. Tous droits réservés.

Implementing a Struct of Arrays

118 pointspar mpweiheril y a 1 jour

16 comments

PessimalDecimalil y a 1 jour
I started thinking this would be a rehashing of how column-oriented storage formats can be far more efficient for certain access patterns. But it really was a showcase of what a bloated mess C++ has become.
评论 #43940598 未加载
评论 #43938351 未加载
评论 #43936886 未加载
评论 #43943872 未加载
Dweditil y a environ 23 heures
Struct of Arrays vs Array of Structs have different performance, depending on how they are accessed, mainly due to how memory will be cached.<p>If you are iterating over objects sequentially, and looking at every field, they will perform about the same. If you are iterating over objects sequentially, and only looking at a few fields, Struct of Arrays performs better. If you are accessing objects at random, and reading every field, Array of Structs performs better.<p>Array of Structs has a multiplication step when you calculate the address of an element. Struct of Arrays basically guarantees that the multiplication will be by a power of 2, so it&#x27;s a bitshift rather than a multiplication. (Unless your struct contains a type whose size is not a power of 2). Multiplication is still very fast though on most architectures, so that&#x27;s not all that much of a difference.
评论 #43939821 未加载
评论 #43941630 未加载
评论 #43939800 未加载
gr4vityWallil y a 1 jour
Interesting article. It does show how modern C++ can be quite scary.<p>It reminded me of a Haxe macro used by the Dune: Spice Wars devs to transform an AoS into a SoA at compile time to increase performance: <a href="https:&#x2F;&#x2F;youtu.be&#x2F;pZcKyqLcjzc?t=941" rel="nofollow">https:&#x2F;&#x2F;youtu.be&#x2F;pZcKyqLcjzc?t=941</a><p>The end result is quite cool, though those compile time type generation macros always look too magical to me. Makes me wonder if just getting values using an index wouldn&#x27;t end up being more readable.
perihelionsil y a environ 24 heures
I attempted to write a minimal version of the idea in Common Lisp, if anyone was curious about how it&#x27;d look like in that language,<p><a href="https:&#x2F;&#x2F;peri.pages.dev&#x2F;struct-of-arrays-snippet" rel="nofollow">https:&#x2F;&#x2F;peri.pages.dev&#x2F;struct-of-arrays-snippet</a>
the__alchemistil y a 1 jour
I think I&#x27;ve lost the thread on the abstractions. (Me not being very familiar with Zig outside of its most basic syntax is probably why.) I&#x27;ve been doing a lot of SoA work in rust lately; specifically because I have numerical&#x2F;scientific code that uses CPU SIMD and CUDA; SoA works great for these.<p>The workflow is, I set up Vec3x8, and Quaternionx8, which wrap a simd instrinsic for each field (x: f32x8, y: f32x8...) etc.<p>For the GPU and general flattening, I just pack the args as Vecs, then the fn signature contains them like eps: &amp;[f32], sigma: &amp;[f32] etc. So, I&#x27;m having trouble mapping this SoA approach to the abstractions used in the article. Then the (C++-like CUDA) kernel sees these as *float3 params etc. It also feels like a complexity reverse of the Rust&#x2F;Zig stereotypes...<p>Examples:<p><pre><code> struct Vec3x8 { x: f32x8, y: f32x8, z: f32x8 } &#x2F;&#x2F; appropriate operator overloads... struct Setup { eps: Vec&lt;f32&gt;, sigma: Vec&lt;f32&gt;, } </code></pre> So, Structs of Arrays, plainly. Are the abstractions used here something like Jai is attempting, where the internal implementation is decoupled from the API, so you don&#x27;t compromise on performance vice ergonomics?
评论 #43943166 未加载
monkeyeliteil y a 1 jour
Interest in SOA is bringing to mind the “art of the meta object protocol” which argues for a stage between class definition and implementation that would allow you to choose the layout and access method for instances of a class.
评论 #43936783 未加载
评论 #43937198 未加载
评论 #43936682 未加载
mac3nil y a 1 jour
JOVIAL language had TABLE structures, which could be declared SERIAL or PARALLEL (<a href="https:&#x2F;&#x2F;ntrl.ntis.gov&#x2F;NTRL&#x2F;dashboard&#x2F;searchResults&#x2F;titleDetail&#x2F;PB82135062.xhtml" rel="nofollow">https:&#x2F;&#x2F;ntrl.ntis.gov&#x2F;NTRL&#x2F;dashboard&#x2F;searchResults&#x2F;titleDeta...</a> page 281).
sphil y a 1 jour
<p><pre><code> define_aggregate(^^Pointers, nsdms(^^T) | std::views::transform([](std::meta::info member){ return data_member_spec(add_pointer(type_of(member)), {.name = identifier_of(member)}); })); </code></pre> What operator is ^^type?
评论 #43937142 未加载
评论 #43937108 未加载
TheHideoutil y a 1 jour
So, basically it&#x27;s allowing you to use a struct like you would in OOP, but get the array benefits of ECS when that struct is in a vector?
评论 #43936879 未加载
评论 #43938144 未加载
评论 #43936448 未加载
jayd16il y a 1 jour
Towards the middle you realize this is about the reflection more than anything else.<p>I do like how directly accessing the fields individually (the whole reason you would do this) is a hypothetical presented as an after thought. Enjoyably absurd.
gpderettail y a 1 jour
The use of reflection is interesting, but is there a significant advantage, compared to something like this:<p><pre><code> template&lt;template&lt;class&gt; class G&gt; struct Point { G&lt;int&gt; x; G&lt;int&gt; y; auto get() { return std::tie(x,y); } }; template&lt;template&lt;template&lt;class&gt; class&gt; class C&gt; struct SOA { template&lt;class T&gt; using Id = T; template&lt;class T&gt; using Ref = T&amp;; C&lt;std::vector&gt; vs; void push_back(C&lt;Id&gt; x) { std::apply([&amp;] (auto&amp;&amp;... r) { std::apply([&amp;](auto&amp;&amp;... v){ ( (r.push_back(v)),...); }, x.get()); }, vs.get()); } C&lt;Ref&gt; operator[](size_t i) { return std::apply([&amp;] (auto&amp;&amp;... r) { return C&lt;Ref&gt;{ r[i]...}; }, vs.get()); } }; int main() { SOA&lt;Point&gt; soa_point; soa_point.push_back({1,2}); auto [x,y] = soa_point[0]; }</code></pre>
评论 #43939479 未加载
ozgrakkurtil y a environ 6 heures
It is skeptical if this is even needed, why not design the structs etc. properly from the start so they are columnar if columnar works better?<p>Meta programming is never free
hinkleyil y a environ 18 heures
The problem I run into with these sorts of structures is the whole aggregation versus composition issue.<p>With composition the SoA problem is pretty simple. This object belongs to an owner or a category and it just never &#x27;moves&#x27; so the most naive solution is just fine.<p>I haven&#x27;t looked at C++ in a million years, but looks like this implementation fixes the aggregation problem by handing out handles to the data, but I don&#x27;t see anything in here where it tries to hand out the same handle for the same offset. I don&#x27;t know about C++ but that matters in some languages.
评论 #43944720 未加载
gwenzekil y a environ 20 heures
Interesting to see the new C++ at work. But also I&#x27;m sure it&#x27;s easier to learn Zig full language that just the new C++ metaprogramming
adzmil y a environ 21 heures
Neat to see the reflection &#x2F; unibrow operator ^^ in the wild!
评论 #43947225 未加载
Enthouanil y a 1 jour
I’m definitely missing the point, but reading the article, I kept thinking &quot;This would’ve been so much easier in C.&quot;
评论 #43937903 未加载
评论 #43937452 未加载
评论 #43938005 未加载