Skip to content

Commit 6be08b8

Browse files
authored
fn decode_coefs_class: Fix branch misprediction (#1246)
* Part of #1180. Move the `tok != 0` check before the `*= 0x17ff41` so that `cmov` is used, not a mispredicted branch.
2 parents a43b380 + ec6c712 commit 6be08b8

File tree

1 file changed

+14
-3
lines changed

1 file changed

+14
-3
lines changed

src/recon.rs

+14-3
Original file line numberDiff line numberDiff line change
@@ -916,12 +916,23 @@ fn decode_coefs<BD: BitDepth>(
916916
rc = rc_i;
917917
} else {
918918
// `0x1` for `tok`, `0x7ff` as bitmask for `rc`, `0x41` for `level_tok`.
919+
920+
// If we do this after the `tok *= 0x17ff41`,
921+
// it uses a mispredicted branch instead of `cmov`.
922+
let tok_non_zero = tok != 0;
923+
919924
let mut tok = tok as u32;
920925
tok *= 0x17ff41;
921926
level[0] = tok as u8;
922-
// `tok ? (tok << 11) | rc : 0`
923-
tok = (tok >> 9) & (rc as u32).wrapping_add(!0x7ff);
924-
if tok != 0 {
927+
let tok_check = if tok != 0 {
928+
((tok as u16) << 11) | rc
929+
} else {
930+
0
931+
};
932+
tok = (tok >> 9) & (rc as u32 + !0x7ff);
933+
debug_assert!(tok == tok_check as u32);
934+
debug_assert!(tok_non_zero == (tok != 0));
935+
if tok_non_zero {
925936
rc = rc_i;
926937
}
927938
cf.set::<BD>(f, t_cf, rc_i as usize, tok.as_::<BD::Coef>());

0 commit comments

Comments
 (0)