From: Alexander Duyck > Sent: 28 February 2017 17:20 ... > You might want to consider just using a combination AND, divide, > multiply, and OR to avoid having to have any conditional branches > being added due to this code path. Basically the logic would look > like: > new = val | NAPIF_STATE_SCHED; > new |= (val & NAPIF_STATE_SCHED) / NAPIF_STATE_SCHED * NAPIF_STATE_MISSED; > > In assembler that all ends up getting translated out to AND, SHL, OR. > You avoid the branching, or MOV/OR/TEST/CMOV type code you would end > up with otherwise.
It is a shame gcc doesn't contain that optimisation. It also doesn't even make a good job of (a & b)/b * c since it always does a shr and a sal (gcc 4.7.3 and 5.4). Worthy of a #define or static inline. Something like: #define BIT_IF(v, a, b) ((b & (b-1) ? (v & a)/a * b : a > b ? (v & a) / (a/b) : (v & a) * (b/a)) David