4 ms·
Unrelated to protection: Ivan mentioned that this is an SSA-like architecture. How does the compiler implement PHIs connecting expressions with different laten
by neerajsi 9y ago
Unrelated to protection: Ivan mentioned that this is an SSA-like architecture.
How does the compiler implement PHIs connecting expressions with different latencies? Let's say I have:
`if (cond) { x = a + b; } else { x = a * b; }`
The MUL is may take a bit longer than the ADD, but the user needs to accept the argument at a given belt position. How do you avoid having the pay the latency cost for the MUL if `cond` is usually true?
- dirkt 9y agoIt's an interesting question, maybe ask at the Mill forum: https://millcomputing.com/forum/the-mill/ https://millcomputing.com/forum/the-mill/ Based on my limited understanding of the Mill I'd say (1) (simple_ PHIs are implemented by the pick-phase, (2) it's an exposed pipeline with known latencies, so you can't really have the "I want to avoid the longer latency inside a single basic block", and it's probably not worth doing that for a single mult vs. a single add, (3) for cases where it matters because the latency difference is much better, you'd use two basic blocks, and rearrange belt positions at the end.
- marcosdumay 9y agoThe talk about the belt explains this. If I remember it right, ADD and MUL take the same time, but when instructions differ in time the compiler is expected to reorder them. If it can't reorder, than yes, it has to wait.
- igodard 9y agoThe tool chain does hoisting and if-conversion with wild abandon. That code becomes {x = cond ? a+b : a*b}, and both expressions are evaluated in parallel. The conversion is a heuristic; if you have tracing data for the branch then it might not convert. However, a miss-predict is a lot more expensive than a multiply so the tracing has to be pretty skewed to be worth the branch. The conversion does increase the latency of getting the value of x. If there's nothing else to do then the tool chain will insert explicit nops to wait for the expression. The same stalls will exist on other architectures for the same code, just not visibly in the code. It happens that making the nops explicit is faster than a stall; you can idle through a nop with no added overhead, but you can't restart a stall instantaneously.