5 ms·
Implement BeamAsm – A JIT for Erlang/OTP
- conradfr 6y agoVery exciting. Also Facebook open-sourcing its static typed Erlang prototype in November.
- ch4s3 6y agoIt seems like 2021 is going to be a big year for BEAM languages.
- tluyben2 6y agoAny idea how they handled static typing for messages? As I remember from previous conversations, that was an issue.
- conradfr 6y agoI only read the slides so I'm not sure but they mention gen_servers so I guess there will be something about messages.
- lf-non 6y agoI may be missing some context but can't it be done similar to how we handle data from outside world in TS ? A runtime type guard that asserts that the shape of data conforms to a particular type and from that point forward compiler will trust the guard and assume that the message is of particular type. In a dynamically typed world, I doubt one could do much better.
- tluyben2 6y agoThe thing is; messages for Erlang are far more part of your programming/architecture than in other languages. You are basically writing 'nanoservices' all the time. I saw quite a lot of people mentioning it in discussions, including here, for instance [0]. [0] https://news.ycombinator.com/item?id=22573535 https://news.ycombinator.com/item?id=22573535
- ramchip 6y agoI love how much thought and polish went into this, just like so many other Erlang features in recent years: counters, persistent_term, thread progress, ETS scaling, process groups... There's been talks of JIT for quite a few years, but they didn't want to merge it in until they had something that's easy to maintain, and doesn't introduce significant performance regressions. The end result looks really solid.
- andy_ppp 6y agoSo this JIT supports everything but HiPE and will be included in OTP-24 and is production ready(???) and dramatically improves performance across almost everything? Seems too good to be true. What has been the bug finding process so far in this PR?
- hinkley 6y agoProbably a case of the low hanging fruit. With most projects you start off with a bunch of improvements with very few side effects - at present - but quickly start to encounter trade offs. Both in the form of new improvements introducing more development overhead, and the fact that open ended things are generally hard to make fast. To make something faster may mean calcifying some part of the architecture; this code handles every scenario that the design defines now, but it can’t handle other scenarios we might have wanted to consider later. Those are now harder to implement or counter to our assumptions. People don’t like it when you take back things you previously gave them, meaning no new feature or a huge opportunity cost for that feature (because it’s reimplementing other features as well as adding a new one).
- andy_ppp 6y agoI don’t think this is at all true... I mean the PR changes 350-odd files and adds some crazy JIT engine. It’s hardly low hanging fruit... I don’t know enough about how this is implemented to say it will make future features harder, they even state in the PR maintenance is very important to the design here so I’ll assume it won’t be a weight around their necks.
- strmpnk 6y agoThis is far from the first JIT effort for BEAM. I'm sure the authors have rolled many years of learnings and experience into this one. Still, you make a good point, it will need a lot of testing by the community before I'd trust it in production.
- metroholografix 6y agoI wish they'd kept it C-only instead of introducing C++ (plenty of runtime code generation libraries written in C). There is something to be said about internal consistency and for a codebase as established as this, C++ is more of a detriment than a gain.
- mouldysammich 6y agoI imagine developers as experienced as the creators of this evaluated the C options and decided C++ was in fact not more of a detriment than a gain. It has its problems but blindly being anti C++ is silly.
- metroholografix 6y agoHardly blindly. It's been a C codebase so far. Introducing C++ makes this no longer the case. This has strong implications for both development and deployment. I'm perplexed since there exist battle-tested code generation engines written in C (e.g. dynasm). Correct me if I'm wrong but it doesn't look like asmjit is anything special in that regard. I can't imagine Joe Armstrong being happy about this.
- tluyben2 6y agoHe might roll over in his grave... I do agree with you though.
- jashmatthews 6y agoDynasm depends on Lua for pre-processing into pure C. I guess you could write an Erlang version? There's a Ruby meta-assembler in Safari JavaScriptCore!
- metroholografix 6y agoDynasm can be compiled with minilua.c (a single file), which can simply be embedded into the Erlang build. https://corsix.github.io/dynasm-doc/tutorial.html https://corsix.github.io/dynasm-doc/tutorial.html
- lpgauth 6y agoThis is amazing. Huge props to Lukas Larsson and the OTP team! Some background on the journey to BeamJIT: https://drive.google.com/file/d/1hHCs90kDX_wJ9AbLzGNu5bZKdIVWsLsg/view https://drive.google.com/file/d/1hHCs90kDX_wJ9AbLzGNu5bZKdIV...
- tedunangst 6y agoSo this is not quite beamjit, but a sort of rewrite?
- filmor 6y agoI understood it as a completely new, simplified approach that Lukas Larsson started beginning of the year. It's not a tracing or optimising JIT, but instead at load time translates the BEAM opcodes to native code using asmjit.
- tiffanyh 6y agoI'm soooooo excited about this. Question: how does performance compare to HiPE. I see reference to improvements over the Interpreter but what about performance vs HiPE?
- nickjj 6y agoCan someone break this down and explain what this means in practical runtime performance gains? I know it's probably "it depends", but in Elixir let's say you were doing a lot of string parsing or mucking around with a bunch of Enum functions or doing a bit of math. Will this put Elixir's performance on par with at least Python and Ruby in those cases? I know this feature is meant for Erlang but I'm assuming it applies back to Elixir too?
- strmpnk 6y agoIt does apply to Elixir. It will help all around performance but more so it does this on a per-instruction level by reducing dispatch cost in that the interpreter pays (as well as managing to specialize things a little better than what the fixed instruction tables can express). To get an idea of the instruction stream of the BEAM (not the same as .beam asm), you can use the erts_debug module: iex> :erts_debug.df(String) This will dump a BEAM machine instruction stream to a file named Elixir.String.dis in your current working directory. You'll see things like: 000000001B81AFB0: i_func_info_IaaI 0 `'Elixir.String'` `at` 2 000000001B81AFD8: is_integer_fx f(000000001B81AFB0) x(1) 000000001B81AFE8: is_ge_literal_fxc f(000000001B81B008) x(1) `0` 000000001B81B000: i_call_only_f loc(`'Elixir.String'`:`do_at`/2) 000000001B81B008: allocate_tt 2 2 000000001B81B010: move_window2_xxy x(1) x(0) y(0) 000000001B81B018: i_call_f loc(`'Elixir.String'`:`length`/1) 000000001B81B020: i_plus_xyjd x(0) y(0) j(0) x(0) 000000001B81B030: is_ge_literal_fxc f(000000001B81B060) x(0) `0` 000000001B81B048: move_shift_yxx y(1) x(0) x(1) 000000001B81B050: i_call_last_fQ loc(`'Elixir.String'`:`do_at`/2) 2 000000001B81B060: move_deallocate_return_cQ `nil` 2 Each of those instructions are what the .beam file loader currently generates. With the JIT, these will be replaced by machine code.