Closed ChrisPenner closed 1 day ago
Hrmm, not sure how Dan's commits somehow got re-included here? I'll figure that out.
Nice!
Count to 1000 337.363µs -> 286.412µs
What do you think is going on here? I would expect we can get this down to 10-20µs based on the previous toy interpreter which was managing 75 million ops / s, which would be about 13µs to count to 1000.
Basically, what's still left todo that we're expecting big gains from, or is this a case of the interpreter being phrased that something isn't being inlined or there's allocation or function call overhead in a place we don't intend?
Nat.drop
is still not a single instruction that gets inlined. That's one of the TBD comments.
Using == 0
also still involves a non-trivial wrapper.
Cody says we're passing the nimbus test-suite, he's going to run it in staging for a bit.
Is this otherwise ready to go?
@dolio it was until I introduced an infinite loop with that most recent change 🙃
Oh, is that why CI has been taking so long? :)
Yup, I had a cyclic pattern definition, just fixing that now :)
Oh, I should probably also give the universalCompare
logic one last check to make sure it's consistent with the old version
When we deployed this to the Unison Cloud staging environment everything worked except we did experience hangs with one specific program. We should hold off on merging this until we figure that out.
Looks like it's up and running on staging now, which was the last blocker.
Merging!
Overview
Up until now, the unboxed stack was used exclusively for control-flow within the interpreter itself; e.g. pattern-matching on data-type tags etc. Primitive types like Int and Nat would be unboxed from the boxed stack before every primitive op, then reboxed afterwards, which introduced ~3 extra instructions per primitive operation.
This change removes all that ceremony and now unboxed values are passed around and operated on directly, no need to repack them in between ops, cutting away those extra ~3 instructions per op.
We'll expect a speed up on primitive operations on unboxed types like addition and subtraction. Everything else should remain about the same.
Implementation notes
data Val = Val !Int !Closure
Test coverage
Benchmarks:
trunk -> this branch
Loose ends
The ANF operations still have
BX
/UN
tags denoting the stack of each arg, but these are redundant and entirely unused, I'll take the time to remove them after this PR, but that's another large sweeping code change and it's good to merge into trunk in between large changes.Note that, for now, we do still store the unboxed value's type on the boxed stack, this is for two reasons:
We may in the future be able to avoid this with some re-arrangements, which would allow us to avoid one extra array write.