6 ms·
Single-Assignment C
- dang 7y agoRelated from 2013: https://news.ycombinator.com/item?id=6949525 https://news.ycombinator.com/item?id=6949525
- jagged-chisel 7y agoI think you mean 2013
- dang 7y agoAh yes. Thanks! Fixed.
- coldtea 7y agop = p + v * dt; v = v + a * dt; How is this "single assignment"? Aren't v and p assigned values already before those lines? Or do they have some default initial value for their type that doesn't count as an assignment?
- Arnavion 7y agoIt's not C, but a new language with similar syntax. Based on reading the docs at [1], the assignment is sugar for generating a new binding for the result of that expression that shadows the previous one. [1]: http://www.sac-home.org/doku.php?id=about:core http://www.sac-home.org/doku.php?id=about:core
- nwallin 7y agoI don't understand. What does the "single assignment" bit get you that a compiler with an SSA pass doesn't?
- jldugger 7y agoI assume the removal of pointer aliasing?
- gengkev 7y agoProbably that the original binding of p is immutable, as it would be in a functional language: you can create a new binding, but you can't actually change the value of the existing binding.
- nwallin 7y agoUnless there's something I don't understand, that's what the single static assignment pass does in a compiler.
- AgentME 7y agoNew bindings live at different addresses (if you pass a pointer to one binding, and then make a new binding with a new value, the existing pointer will point to the old value and not the new binding's value) and bindings made in a loop iteration won't live to the next iteration.
- lostmsu 7y agoThis sounds like an implementation detail. What does the language spec say about the outcome.
- AgentME 7y agoDifferent bindings are like entirely different variables that just coincidentally share the same name.
- a1369209993 7y agoThe (C) language spec says that: x = 5; int* p = &x; x = 6; // new binding of x printf("%i\n",*p); prints "6". If new bindings lived at different addresses, it would print "5".
- seanmcdirmid 7y agoMaybe it’s short for: p[t+dt] = p[t]+v[t]*dt v[t+dt] = v[t]+a[t]*dt ?
- slavik81 7y agoAs an aside, v = v + a * dt; p = p + v * dt; is typically more accurate. The first form is Forward Euler integration [1], while my suggestion is Semi-implicit Euler [2]. [1]: https://en.wikipedia.org/wiki/Euler_method https://en.wikipedia.org/wiki/Euler_method [2]: https://en.wikipedia.org/wiki/Semi-implicit_Euler_method https://en.wikipedia.org/wiki/Semi-implicit_Euler_method
- WalterBright 7y agoI thought this was about adopting a programming style where each variable is assigned to only once. But it was something else entirely. I was interested because I've started adopting the single assignment style in my own code, and like the results (the code is easier to comprehend).
- glouwbug 7y agoAgreed, I'm currently taking a similar approach, but forgoing pointers as much as possible as well. This leads to structs being passed by value, and const abuse. Ray h_cast(const Hero hero, const Hit hit, const Sheer sheer, const int yres, const int xres) { const Point end = p_sub(hit.where, hero.where); const Point corrected = p_turn(end, -hero.yaw); const Line trace = { hero.where, hit.where }; const Projection projection = p_project(yres, xres, hero.fov.a.x, hero.pitch, corrected, hero.height); const Ray ray = { trace, corrected, p_sheer(projection, sheer), hit.surface, hit.offset, hero.torch }; return ray; } It leads to some nice somewhat functional styles. I estimate its 80% pure, given its C99 alone. I've adopted this style in my Age of Empires 2 engine rewrite if anyone is curious: https://github.com/glouw/openempires https://github.com/glouw/openempires As for performance I am heavily relying on LTO. I seem to get a 50% performance boost with pass by values on structs - as I've sedded openempires to replace occurrences of _Type name_ with C++'s _Type& name_ for all functions arguments - and the added pointer aliasing and de-references bogged the engine down in heavily forested areas. Compilers love singly assigned const values, and seem to suffer under heavy pointer aliasing.
- saagarjha 7y ago> I've sedded openempires to replace occurrences of _Type name_ with C++'s _Type& name_ for all functions arguments This isn’t a valid transformation :/ > Compilers love singly assigned const values I mean, they’re going to convert to SSA for you anyways. > and seem to suffer under heavy pointer aliasing Have you tried restrict?
- voldacar 7y ago> This leads to structs being passed by value do compilers generally optimize this away on -O3, or do you just accept the performance hit in exchange for prettier code?
- kick 7y agoThis is interesting; I just investigated SAC for the first time about seven hours ago (I actually posted a license-fragment from it on my social media account: https://blob.cat/notice/9qMowPTjR9F7fjid3Q https://blob.cat/notice/9qMowPTjR9F7fjid3Q), finding it technically impressive but unfortunately proprietary. Was there news about it, or something? It came to mind because something I was wanting to try depended on it, and it doesn't get posted to HN very often, so I'm really curious as to how you found it.
- HeraldEmbar 7y agoThe home page is fairly free of any details about SaC, though I do now know an awfully lot about who is involved. Also, there's no reference manual. Where can I find a tutorial, examples, or any concrete details?
- antonvs 7y agoThere's a docs page linked from the home page with a tutorial and various other docs: http://www.sac-home.org/doku.php?id=docs:main http://www.sac-home.org/doku.php?id=docs:main