]> git.ipfire.org Git - thirdparty/zstd.git/commitdiff
ZSTD_fast_noDict: Minimize Checks When Writing Hash Table for ip1
authorW. Felix Handte <w@felixhandte.com>
Tue, 10 May 2022 21:29:39 +0000 (14:29 -0700)
committerW. Felix Handte <w@felixhandte.com>
Tue, 10 May 2022 21:29:39 +0000 (14:29 -0700)
This commit avoids checking whether a hashtable write is safe in two of the
three match-found paths in `ZSTD_compressBlock_fast_noDict_generic`. This pro-
duces a ~0.5% speed-up in compression.

A comment in the code describes why we can skip this check in the other two
paths (the repcode check and the first match check in the unrolled loop).

A downside is that in the new position where we make this check, we have not
yet computed `mLength`. We therefore have to avoid writing *possibly* dangerous
positions, rather than the old check which only avoids writing *actually*
dangerous positions. This leads to a miniscule loss in ratio (remember that
this scenario can only been triggered in very negative levels or under incomp-
ressibility acceleration).

lib/compress/zstd_fast.c

index 198ccaee36f47fad6ef2bd4942375909d6b0fef1..f2028ef358974ab0c92b3ecdeba9885b5479ac04 100644 (file)
@@ -224,6 +224,23 @@ _start: /* Requires: ip0 */
         /* check match at ip[0] */
         if (MEM_read32(ip0) == mval) {
             /* found a match! */
+            if (step > 4) {
+                /* We need to avoid writing an index into the hash table >= the
+                 * position at which we will pick up our searching after we've
+                 * taken this match.
+                 *
+                 * The minimum possible match has length 4, so the earliest ip0
+                 * can be after we take this match will be the current ip0 + 4.
+                 * ip1 is ip0 + step - 1. If ip1 is >= ip0 + 4, we can't safely
+                 * write this position. The expedient thing to do is just to
+                 * write a bad position.
+                 *
+                 * We perform this check here, separate from the write, because
+                 * this is the only match path where this can occur. (In rep-
+                 * code and the first match checks, ip1 == ip0 + 1.)
+                 */
+                ip1 = base;
+            }
             goto _offset;
         }
 
@@ -288,9 +305,7 @@ _match: /* Requires: ip0, match0, offcode */
     anchor = ip0;
 
     /* write next hash table entry */
-    if (ip1 < ip0) {
-        hashTable[hash1] = (U32)(ip1 - base);
-    }
+    hashTable[hash1] = (U32)(ip1 - base);
 
     /* Fill table and check for immediate repcode. */
     if (ip0 <= ilimit) {