sillycross
Joined 6 years ago
Joined 6 years ago
If LuaJIT interpreter were to employ IC, it would have to undergo a major rewrite (due to its assembly nature) to have the equally efficient code as LJR (that we generate automatically). This is one advantage of our meta-compiler approach.
Finally, although no experiment is made, my subjective opinion is already in the article:
> LuaJIT’s hand-written assembly interpreter is highly optimized already. Our interpreter generated by Deegen is also highly optimized, and in many cases, slightly better-optimized than LuaJIT. However, the gain from those low-level optimizations are simply not enough to beat LuaJIT by a significant margin, especially on a modern CPU with very good instruction-level parallelism, where having a few more instructions, a few longer instructions, or even a few more L1-hitting loads have negligible impact on performance. The support of inline caching is one of the most important high-level optimizations we employed that contributes to our performance advantage over LuaJIT.
That is, if you compare the assembly between LJR and LuaJIT interpreter, I believe LJR's assembly is slightly better (though I would anticipate only marginal performance difference). But that's also because we employed a different boxing scheme (again...). If you force LJR to use LuaJIT's boxing scheme, I guess the assembly code would also be similar since LJR's hand-written assembly is already optimal or at least very close to optimal.
However, I'm not sure if doing so is useful or necessary. Interpreter performance is sensitive to code layout (which affects hardware branch predictor accuracy), but I don't think there is a general way to optimize the code layout to make the branch predictor as happy as possible.
So if you changed your code alignment and saw a perf change, it's more likely caused by the random perf gain/loss due to code layout change, not because that 1-byte-alignment is better than 16-byte-alignment or vice versa.
[1] https://easyperf.net/blog/2018/01/25/Code_alignment_options_...
As explained in the article, LLVM already has the calling convention you are exactly looking for: the GHC convention (cc 10). You can use it to "pin" registers by passing arguments at the right spot. If you pin your argument in a callee-saved register of the C calling conv, it won't get clobbered after you do a C call.
I think the point you missed is: the function 'cellContainsLiveObject' is not used by GC, it is used by allocator to tell if the cell is available for allocation. So it's fine if the function returns true but the object is actually unreachable, but not the other way around.
I am in full support with this, though it seems to me this is too idealized to be practical in practice. How can one reach a fair judgement of a student only based on a 1000-word essay in his/her application (which might not even be written by him/herself)?
However, I'm still saddened by that the MIT response to this incident is simply "it is Abbot's right of free expression to say whatever he wants", but nothing about what he actually said, or whether it at least makes some sense. It's as if MIT treated Abbot as an unknowing child whose nonsense words shall be tolerated, which is disturbing. Below is part of the mail list letter I received:
> Freedom of expression is a fundamental value of the Institute.
> I believe that, as an institution of higher learning, we must ensure that different points of view – even views that some or all of us may reject – are allowed to be heard and debated at MIT. Open dialogue is how we make each other wiser and smarter.
> This commitment to free expression can carry a human cost. The speech of those we strongly disagree with can anger us. It can disgust us. It can even make members of our own community feel unwelcome and illegitimate on our campus or in their field of study.
> I am convinced that, as an institution, we must be prepared to endure such painful outcomes as the price of protecting free expression – the principle is that important.
It's actually an interesting example where undefined behavior allowed compiler optimization:
(1) dereferencing an invalid pointer is UD
(2) signed integer overflow is UD.
This allows the compiler to assume that the program never crashes and the counter never overflows. The loop is then optimized out knowing that it is read-only thus has no side-effects.
I never thought before that ISPs would really keep track of every user's browsing history, but apparently as cheap as the disks are today, this has become true. Can't think of any use of this data other than for mass surveillance.
> "there’s only so much one can do without touching the data model"
You probably want to look at the other link in that PR, which demonstrated how well copy-and-patch can do for another dynamic language (Lua): [1]
Of course, whether or not CPython could eventually make it to that point (or even further) is a different story: they are under a way tighter constraint than just developing something for academia. But copy-and-patch can do a lot even for dynamic languages :)
[1] https://sillycross.github.io/2023/05/12/2023-05-12/