Skip to content

Commit 315b663

Browse files
committed
Inflate: Use zero-latency refill strategy
This requires refilling while there are still enough bits in the buffer for the next table lookup. The next table lookup can then use the old bit-buffer and then shift the refilled bit-buffer, completely removing the refill from the critical path.
1 parent efa5a2d commit 315b663

File tree

1 file changed

+22
-2
lines changed

1 file changed

+22
-2
lines changed

inffast_chunk.c

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,11 +167,20 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
167167
memcpy(&here, &here32, sizeof(code)); \
168168
} while (0)
169169

170+
if (bits < 10) {
171+
REFILL();
172+
}
173+
170174
/* decode literals and length/distances until end-of-block or not enough
171175
input data or output space */
172176
do {
173-
REFILL();
177+
uint64_t next_hold = hold | (read64le(in) << bits);
178+
in += 7;
179+
uint64_t tmp = ((bits >> 3) & 7);
180+
in -= tmp;
181+
bits |= 56;
174182
TABLE_LOAD(lcode, hold & lmask);
183+
hold = next_hold;
175184
old = hold;
176185
hold >>= here.bits;
177186
bits -= here32;
@@ -223,9 +232,20 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
223232
break;
224233
}
225234
#endif
235+
if (unlikely((bits & 63) < 10)) {
236+
REFILL();
237+
}
238+
226239
/* preload and shift for next iteration */
227-
REFILL();
240+
uint64_t next_hold = hold | (read64le(in) << bits);
241+
in += 7;
242+
asm volatile ("" : "+r"(in));
243+
uint64_t tmp = ((bits >> 3) & 7);
244+
asm volatile ("" : "+r"(tmp));
245+
in -= tmp;
246+
bits |= 56;
228247
TABLE_LOAD(lcode, hold & lmask);
248+
hold = next_hold;
229249
old = hold;
230250
hold >>= here.bits;
231251
bits -= here32;

0 commit comments

Comments
 (0)