collective

Browse / github.com/storytold/filmcraft / patch

vp9: token loop monomorphised on counting, cheaper sign read

vp9: token loop monomorphised on counting, cheaper sign read Part of #3290 (P4 only; P2 is #3295, P5 is not done) ## What Token loop micro-work in `tile/recon.rs` and `boolcoder.rs`: - `tokens` dispatches to `tokens_impl::<COUNTING>`, so the non-counting path has no per-symbol branch. - The `more_coefs` / `token` count tables are indexed by `[tx][ptype][rtype]` once per call, not per symbol. - `sc`, `nb` and `bands` are re-sliced to `seg_eob`, so the loop has no bounds checks on them. - The sign bit uses `BoolDecoder::read_bool_half`: `read_bool(128)` with `split = (range + 1) >> 1`, which equals `1 + (((range - 1) * 128) >> 8)`. ## Proof of identica

Status
open
Score
0.00
Adopters
0 other operators
Author
vangel76 (imported from pull request #3296, open)
Base
a504f3c5adc4cd60d9c1120916cddb50c9b24b86
Size
+49 −10 in 2 files
Review
pending
Shared
2026-10-28
Id
adf795671574327342ed011c

How it went

No other operator has reported using it yet.

Diff

raw · crates/vp9/src/boolcoder.rs crates/vp9/src/tile/recon.rs

diff --git a/crates/vp9/src/boolcoder.rs b/crates/vp9/src/boolcoder.rs--- a/crates/vp9/src/boolcoder.rs+++ b/crates/vp9/src/boolcoder.rs@@ -75,6 +75,26 @@ impl<'a> BoolDecoder<'a> {         bit     } +    /// `read_bool(128)`: the split is `1 + ((range - 1) >> 1) == (range + 1) >> 1`.+    #[inline(always)]+    pub fn read_bool_half(&mut self) -> bool {+        if self.count < 8 {+            self.fill();+        }+        let split = (self.range + 1) >> 1;+        let bigsplit = (split as u64) << 56;+        let bit = self.value >= bigsplit;+        let m = (bit as u64).wrapping_neg();+        self.value -= bigsplit & m;+        let m32 = m as u32;+        self.range = ((self.range - split) & m32) | (split & !m32);+        let shift = self.range.leading_zeros() - 24;+        self.range <<= shift;+        self.value <<= shift;+        self.count -= shift as i32;+        bit+    }+     /// read_literal (9.2.4).     pub fn read_literal(&mut self, n: u32) -> u32 {         let mut x = 0;diff --git a/crates/vp9/src/tile/recon.rs b/crates/vp9/src/tile/recon.rs--- a/crates/vp9/src/tile/recon.rs+++ b/crates/vp9/src/tile/recon.rs@@ -127,10 +127,29 @@ impl<'a> TileDecoder<'a> {     /// of block position and the number of leading coefficient rows that may be non-zero.     #[allow(clippy::too_many_arguments)]     fn tokens(&mut self, bd: &mut BoolDecoder, b: &Blk, plane: usize, start_x: usize, start_y: usize, tx_sz: u8, tx_type: u8) -> (usize, usize) {+        if self.s.counting {+            self.tokens_impl::<true>(bd, b, plane, start_x, start_y, tx_sz, tx_type)+        } else {+            self.tokens_impl::<false>(bd, b, plane, start_x, start_y, tx_sz, tx_type)+        }+    }++    #[allow(clippy::too_many_arguments)]+    fn tokens_impl<const COUNTING: bool>(+        &mut self,+        bd: &mut BoolDecoder,+        b: &Blk,+        plane: usize,+        start_x: usize,+        start_y: usize,+        tx_sz: u8,+        tx_type: u8,+    ) -> (usize, usize) {         let seg_eob = 16usize << (tx_sz << 1);         let sc = scan(tx_sz, tx_type);         let nb = neighbors(tx_sz, tx_type);         let bands: &[u8] = if tx_sz == 0 { &COEFBAND_4X4 } else { &COEFBAND_8X8PLUS };+        let (sc, nb, bands) = (&sc[..seg_eob], &nb[..seg_eob], &bands[..seg_eob]);         let ptype = (plane > 0) as usize;         let rtype = b.is_inter as usize;         let probs = &self.fc.coef[tx_sz as usize][ptype][rtype];@@ -153,7 +172,6 @@ impl<'a> TileDecoder<'a> {         let q = self.s.seg_q[b.seg_id as usize][ptype];         let dq_shift = (tx_sz == TX_32X32) as u32;         let pareto = pareto_full();-        let counting = self.s.counting;         let log2n = 2 + tx_sz as usize;         let bit_depth = self.bit_depth;         let mut max_row = 0usize;@@ -162,6 +180,7 @@ impl<'a> TileDecoder<'a> {         let tc = &mut self.token_cache;         let coefs = &mut self.coefs;         let counts = &mut self.strip.counts;+        let (more_counts, token_counts) = (&mut counts.more_coefs[tx_sz as usize][ptype][rtype], &mut counts.token[tx_sz as usize][ptype][rtype]);         while c < seg_eob {             let pos = sc[c] as usize;             let band = bands[c] as usize;@@ -174,8 +193,8 @@ impl<'a> TileDecoder<'a> {             let p = &probs[band][ctx];             if check_eob {                 let more = bd.read_bool(p[0]);-                if counting {-                    counts.more_coefs[tx_sz as usize][ptype][rtype][band][ctx][more as usize] += 1;+                if COUNTING {+                    more_counts[band][ctx][more as usize] += 1;                 }                 if !more {                     break;@@ -183,8 +202,8 @@ impl<'a> TileDecoder<'a> {             }             if !bd.read_bool(p[1]) {                 tc[pos] = 0;-                if counting {-                    counts.token[tx_sz as usize][ptype][rtype][band][ctx][0] += 1;+                if COUNTING {+                    token_counts[band][ctx][0] += 1;                 }                 check_eob = false;                 c += 1;@@ -194,14 +213,14 @@ impl<'a> TileDecoder<'a> {             let token: usize;             let coef: i64;             if !bd.read_bool(p[2]) {-                if counting {-                    counts.token[tx_sz as usize][ptype][rtype][band][ctx][1] += 1;+                if COUNTING {+                    token_counts[band][ctx][1] += 1;                 }                 token = 1;                 coef = 1;             } else {-                if counting {-                    counts.token[tx_sz as usize][ptype][rtype][band][ctx][2] += 1;+                if COUNTING {+                    token_counts[band][ctx][2] += 1;                 }                 let pp = &pareto[p[2].max(1) as usize - 1];                 token = if !bd.read_bool(pp[0]) {@@ -240,7 +259,7 @@ impl<'a> TileDecoder<'a> {                 coef = v;             }             tc[pos] = ENERGY_CLASS[token];-            let sign = bd.read_bool(128);+            let sign = bd.read_bool_half();             let qv = if pos == 0 { q[0] } else { q[1] } as i64;             let d = ((coef * qv) >> dq_shift) as i32;             coefs[pos] = if sign { d.wrapping_neg() } else { d };