Corsix writes low-level posts on CPU instructions, SIMD, CRC performance, LuaJIT and processor architecture.
HN links his posts on Galois field instructions, fast CRC32-C, ARM instructions and malicious LuaJIT bytecode as useful technical references.
A sidenote on JIT: I wrote the following while working out the structure of my post; I figured it wouldn't hurt too much to post it too. The bulk of my question is above; what follows is more or less incidental.
I understand that JIT has something of a role in performance, and that modern Javascript engines couple the performance gains of JIT execution with a mind-boggling slew of different security and sandboxing techniques that aim to prevent unwanted data colliding with the CPU's instruction pointer while still allowing near-C levels of performance. Thing is, what generally makes browsers' sometimes unbelievable JIT-powered performance[1] possible is the fact that the major JS engines - V8, JavaScriptCore, Chakra, Spidermonkey - have huge companies behind them that have the resources to fund continuous R&D to iterate on performance while keeping abreast of security issues.
[1]: http://www.gopherjs.org/blog/2015/09/28/surprises-in-gopherjs-performance/
But I'm not a browser manufacturer, or a computer science major (or even undergrad). I'm just a tinkerer who wants to play around with ideas that generally need safe remote code execution in a way that is transparent (to the extent a high-level competent end user could introspect all operations and control low-level settings) and trustable (for both the end user, who wants control of their device, and the developer, who wants a predictable environment).
I understand that JIT is generally incredibly hard to get right -…
seriously?
You have to know perl's control flow ("unless"
unless is that difficult to understand? Its plain english has totally understandable semantics without reading a lick of documentation about perl.
you have to know perl references(->)
This is just like C++ and an arrow is pretty dang readable and plain to me. Perhaps even more informative than a period.
you have to know perl's variable prefixes.
I might be convinced to give you this one but really reading the perl code isn't that difficult even with 3 extra symbols to know. Even not knowing the symbols the code example you show is both readable and concise.
Yes perl may have some quirks but for the most part it "Does exactly what you think it would by reading it". That was a design goal of the language after all.
Of course anyone could write perl code that is incomprehensible and makes use of perls semantics to obfuscate their purpose (using every example you cite) but that is with effort on their part and significant effort in some cases. And just to drive the point home may I present lua code that is way harder to read than any perl code I've ever seen even in an obfuscated perl contest: http://www.corsix.org/content/obfuscated-lua
To reiterate, no one in their right mind would right lua code like that except as an exercize and experiment. Same thing goes for perl. The perl code you show above is perfectly readable. Unless does exactly what you expect it to. -> arrows mean exactly what you would…
If you learn AVX2 programming via highload, my impression is that NEON is quite similar. The main difference is the lack of movemask. You can read these[0] articles[1] about what to do instead.
For SVE, prior to very recent versions of SVE, there was no tblq (pshufb equivalent) so I didn't have much hope for using it for general-purpose programming, though of course it would be fine for stuff like TFA.
[0]: https://community.arm.com/arm-community-blogs/b/infrastructure-solutions-blog/posts/porting-x86-vector-bitmask-optimizations-to-arm-neon
[1]: https://www.corsix.org/content/whirlwind-tour-aarch64-vector-instructions
Note that loading (maliciously crafted) bytecode is generally not safe in Lua; sandboxing can be escaped in more ways than what's possible when loading plaintext sourcecode, and there are no full mitigations for this currently as far as I know (and would probably be highly interpreter/version sensitive anyway)-- the only "real" mitigation strategy is to just not `load` bytecode at all.
But this is probably a non-issue for a lot of usecases.
See e.g.
https://gist.github.com/corsix/6575486
https://www.corsix.org/content/malicious-luajit-bytecode
There's a problem---you can break out of Lua with malformed bytecode [1] and the Lua team don't want to spend the time trying to validate Lua byte code [2]. That's why the latest Lua version has an option to ignore precompiled Lua scripts.
And sadly, I can see the same happening here.
[1] https://www.corsix.org/content/malicious-luajit-bytecode
[2] The overhead will eat any performance gained by using precompiled Lua code in the first place.
A small history of LuaJIT sandbox escapes:
- 5.2, 2016: https://apocrypha.numin.it/talks/lua_bytecode_exploitation.pdf (9MB PDF)
- 5.2, 2016: https://github.com/erezto/lua-sandbox-escape
- 5.1, 2015: https://www.corsix.org/content/malicious-luajit-bytecode (warning: dense)
There's a "luarop" link (boop.i0i0.me/blog.lua/luarop) referenced in the PDF, but the link sadly seems to have died (IA never crawled the domain).