🏳️‍⚧️ and I make good posts sometimes!

pfp by me!
banner by https://twitter.com/spect_ion


fediverse
‪@PolyWolf@social.treehouse.systems‬
bluesky
@wolf.girl.technology
You must log in to comment.

in reply to @Quelklef's post:

lol I took your post as something of a joke, given that they're incompatible. How would you verifying that information at runtime except to perform runtime analysis (using what amounts to predicates)?

in reply to @PolyWolf's post:

i am! it's something i've been curious about for some time. I'm glad you posted it

can I ask a question about it? There is one thing I don't understand

that is how the optimized code achieves speedups if it still has to double-check that the speculations made were correct.

to use a (modified) example from the article, compare an "unoptimized" version of an int addition:

int32_t left = ...;
int32_t right = ...;
int32_t intResult;
JSValue result;
if (addOverflowed(left, right, &intResult)) {
    result = jsNumber(static_cast<double>(left) +
                      static_cast<double>(right));
} else
    result = jsNumber(intResult);

to the "optimized" version:

int32_t left = ...;
int32_t right = ...;
int32_t result;
speculate(!addOverflowed(left, right, &result));

Both perform a native i32 addition, check if it overflowed, and defer to a slow case if it did. The logic is essentially equivalent. where's the speedup?

i thought perhaps speedup came from being able to use the result of a passed type-check more than once. So an imperative isPrime function, for instance, would see speedup because it would only have to check once that its input is an i32 and from then on could use native i32 operations without any further checks, and could perform compiler optimizations knowing the ops are i32 ops.

But in the example I provided, we're speculating on whether or not an addition overflows, which is information that can't be used more than once, as the overflow status of one addition has no bearing on that of future additions. so clearly my hypothesis is not correct

isn't that answered in the following paragraph? keeping things as integers lets you do "pointer math" (indexing into arrays) without a costly double -> integer conversion.

also, jsNumber is definitionally a double, so the last line of the first code block is also doing an extra integer -> double conversion. that's what this overflow speculation is all about: avoiding those roundtrips.

ohhh, ok, I think I get it. The overflow speculation is useful because on overflow we have to convert back to float. Right. I'm not sure how I missed that, it's literally in the example i gave. thank you!

overall to answer the question "how does code achieve speedups if it has to check that speculations are correct", i believe a large part of the answer is "CPU branch predictors love when you always take one side of a conditional branch"

I’ve finally finished reading this (over the past two months), now I’ve got the hotspot and in-line caching papers to read next! It’s quite neat to see how jscore puts all these ideas together