4 ms·
I would have expected to see the "jo" instructions in the assembly. Does anyone know why it was not used?
by jerven 12y ago
I would have expected to see the "jo" instructions in the assembly. Does anyone know why it was not used?
- Someone 12y agoAssuming that means "jump on overflow": branches are bad for your pipelines, so one should, in general, avoid them if possible. These functions easily can do without jumps (but, presumably, the caller will branch depending on their result)
- nkurz 12y agoAllow me to tilt at a windmill: even if you are optimizing code at this level, there is no reason to avoid branches. On a modern processor, a correctly predicted branch-not-taken will almost always be free. Not just inexpensive, actually free, since a superscalar processor can execute it on an otherwise unused port. A correctly predicted branch-taken will not take more than a single extra cycle. And branch prediction is good enough that you can presume that if a pattern exists, it will be correctly predicted. The thing that can be expensive is a mispredicted branch in a tight loop. That will cost you about 15 cycles (about twice as much as accessing L1, and 1/10th the price of hitting RAM). In a case like this, unless you are expecting an unpredictable mix of overflow and non-overflow, branches are not a problem. If the overflow is going to happen less than 10% of the time, using "jo" (jump overflow) after a numeric operation will be the fastest option.
- gsg 12y agoBecause the function doesn't have anywhere to jump to. Instead it generates zero-or-one from the overflow flag (with seto) and the caller will then do something like test eax, eax/jnz handle_overflow. In other words, the abstraction boundary introduced by the function call mechanism gets in the way of using the overflow flag directly with jo. Inlining would, presumably, re-expose the opportunity.
- jerven 12y agoThat is another part I missed, the ASM implementation seemed to optimise the function while potentially deoptimising the whole program. For most code overflows are rare, jumping to deal with the rare cases but otherwise just doing the normal is often best for whole program performance. But to be honest I am not current in assembly as I like managed languages to much.