]> git.ipfire.org Git - thirdparty/zstd.git/commitdiff
Hash Long One Position Ahead (+2.5% Speed)
authorW. Felix Handte <w@felixhandte.com>
Thu, 2 Sep 2021 16:25:08 +0000 (12:25 -0400)
committerW. Felix Handte <w@felixhandte.com>
Tue, 5 Oct 2021 18:54:37 +0000 (14:54 -0400)
Aside from maybe a latency win in the loop, this means that when we find a
short match, we've already done the hash we need to check the next long match.

lib/compress/zstd_double_fast.c

index 0cf2d2159ffc42582a9da227cf7c5b77167ea656..4e38e4662e00fbb36e3780148140862c59fc3f34 100644 (file)
@@ -118,10 +118,11 @@ _start:
         goto _cleanup;
     }
 
+    hl0 = ZSTD_hashPtr(ip, hBitsL, 8);
+
     /* Main Search Loop */
     do {
         curr = (U32)(ip-base);
-        hl0 = ZSTD_hashPtr(ip, hBitsL, 8);
         hs0 = ZSTD_hashPtr(ip, hBitsS, mls);
         idxl0 = hashLong[hl0];
         idxs0 = hashSmall[hs0];
@@ -148,6 +149,8 @@ _start:
             }
         }
 
+        hl1 = ZSTD_hashPtr(ip1, hBitsL, 8);
+
         if (idxs0 > prefixLowestIndex) {
             /* check prefix short match */
             if (MEM_read32(matchs0) == MEM_read32(ip)) {
@@ -155,18 +158,20 @@ _start:
             }
         }
 
-        if (ip >= nextStep) {
-            PREFETCH_L1(ip + 64);
-            PREFETCH_L1(ip + 128);
+        if (ip1 >= nextStep) {
+            PREFETCH_L1(ip1 + 64);
+            PREFETCH_L1(ip1 + 128);
             step++;
             nextStep += kStepIncr;
         }
-        ip += step;
+        ip = ip1;
+        ip1 += step;
 
+        hl0 = hl1;
 #if defined(__aarch64__)
         PREFETCH_L1(ip+256);
 #endif
-    } while (ip < ilimit);
+    } while (ip1 < ilimit);
 
 _cleanup:
     /* save reps for next block */
@@ -177,8 +182,7 @@ _cleanup:
     return (size_t)(iend - anchor);
 
 _search_next_long:
-    {   hl1 = ZSTD_hashPtr(ip+1, hBitsL, 8);
-        idxl1 = hashLong[hl1];
+    {   idxl1 = hashLong[hl1];
         matchl1 = base + idxl1;
         hashLong[hl1] = curr + 1;