snappy/snappy-internal.h

151 lines
5.3 KiB
C
Raw Normal View History

// Copyright 2008 Google Inc. All Rights Reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Internals shared between the Snappy implementation and its unittest.
#ifndef THIRD_PARTY_SNAPPY_SNAPPY_INTERNAL_H_
#define THIRD_PARTY_SNAPPY_SNAPPY_INTERNAL_H_
#include "snappy-stubs-internal.h"
namespace snappy {
namespace internal {
class WorkingMemory {
public:
WorkingMemory() : large_table_(NULL) { }
~WorkingMemory() { delete[] large_table_; }
// Allocates and clears a hash table using memory in "*this",
// stores the number of buckets in "*table_size" and returns a pointer to
// the base of the hash table.
uint16* GetHashTable(size_t input_size, int* table_size);
private:
uint16 small_table_[1<<10]; // 2KB
uint16* large_table_; // Allocated only when needed
DISALLOW_COPY_AND_ASSIGN(WorkingMemory);
};
// Flat array compression that does not emit the "uncompressed length"
// prefix. Compresses "input" string to the "*op" buffer.
//
// REQUIRES: "input_length <= kBlockSize"
// REQUIRES: "op" points to an array of memory that is at least
// "MaxCompressedLength(input_length)" in size.
// REQUIRES: All elements in "table[0..table_size-1]" are initialized to zero.
// REQUIRES: "table_size" is a power of two
//
// Returns an "end" pointer into "op" buffer.
// "end - op" is the compressed size of "input".
char* CompressFragment(const char* input,
size_t input_length,
char* op,
uint16* table,
const int table_size);
// Return the largest n such that
//
// s1[0,n-1] == s2[0,n-1]
// and n <= (s2_limit - s2).
//
// Does not read *s2_limit or beyond.
// Does not read *(s1 + (s2_limit - s2)) or beyond.
// Requires that s2_limit >= s2.
//
// Separate implementation for x86_64, for speed. Uses the fact that
// x86_64 is little endian.
#if defined(ARCH_K8)
static inline int FindMatchLength(const char* s1,
const char* s2,
const char* s2_limit) {
assert(s2_limit >= s2);
int matched = 0;
// Find out how long the match is. We loop over the data 64 bits at a
// time until we find a 64-bit block that doesn't match; then we find
// the first non-matching bit and use that to calculate the total
// length of the match.
while (PREDICT_TRUE(s2 <= s2_limit - 8)) {
Change a few branch annotations that profiling found to be wrong. Overall performance is neutral or slightly positive. Westmere (64-bit, opt): Benchmark Base (ns) New (ns) Improvement -------------------------------------------------------------------------------------- BM_UFlat/0 73798 71464 1.3GB/s html +3.3% BM_UFlat/1 715223 704318 953.5MB/s urls +1.5% BM_UFlat/2 8137 8871 13.0GB/s jpg -8.3% BM_UFlat/3 200 204 935.5MB/s jpg_200 -2.0% BM_UFlat/4 21627 21281 4.5GB/s pdf +1.6% BM_UFlat/5 302806 290350 1.3GB/s html4 +4.3% BM_UFlat/6 218920 219017 664.1MB/s txt1 -0.0% BM_UFlat/7 190437 191212 626.1MB/s txt2 -0.4% BM_UFlat/8 584192 580484 703.4MB/s txt3 +0.6% BM_UFlat/9 776537 779055 591.6MB/s txt4 -0.3% BM_UFlat/10 76056 72606 1.5GB/s pb +4.8% BM_UFlat/11 235962 239043 737.4MB/s gaviota -1.3% BM_UFlat/12 28049 28000 840.1MB/s cp +0.2% BM_UFlat/13 12225 12021 886.9MB/s c +1.7% BM_UFlat/14 3362 3544 1004.0MB/s lsp -5.1% BM_UFlat/15 937015 939206 1048.9MB/s xls -0.2% BM_UFlat/16 236 233 823.1MB/s xls_200 +1.3% BM_UFlat/17 373170 361947 1.3GB/s bin +3.1% BM_UFlat/18 264 264 725.5MB/s bin_200 +0.0% BM_UFlat/19 42834 43577 839.2MB/s sum -1.7% BM_UFlat/20 4770 4736 853.6MB/s man +0.7% BM_UValidate/0 39671 39944 2.4GB/s html -0.7% BM_UValidate/1 443391 443391 1.5GB/s urls +0.0% BM_UValidate/2 163 163 703.3GB/s jpg +0.0% BM_UValidate/3 113 112 1.7GB/s jpg_200 +0.9% BM_UValidate/4 7555 7608 12.6GB/s pdf -0.7% BM_ZFlat/0 157616 157568 621.5MB/s html (22.31 %) +0.0% BM_ZFlat/1 1997290 2014486 333.4MB/s urls (47.77 %) -0.9% BM_ZFlat/2 23035 22237 5.2GB/s jpg (99.95 %) +3.6% BM_ZFlat/3 539 540 354.5MB/s jpg_200 (73.00 %) -0.2% BM_ZFlat/4 80709 81369 1.2GB/s pdf (81.85 %) -0.8% BM_ZFlat/5 639059 639220 613.0MB/s html4 (22.51 %) -0.0% BM_ZFlat/6 577203 583370 249.3MB/s txt1 (57.87 %) -1.1% BM_ZFlat/7 510887 516094 232.0MB/s txt2 (61.93 %) -1.0% BM_ZFlat/8 1535843 1556973 262.2MB/s txt3 (54.92 %) -1.4% BM_ZFlat/9 2070068 2102380 219.3MB/s txt4 (66.22 %) -1.5% BM_ZFlat/10 152396 152148 745.5MB/s pb (19.64 %) +0.2% BM_ZFlat/11 447367 445859 395.4MB/s gaviota (37.72 %) +0.3% BM_ZFlat/12 76375 76797 306.3MB/s cp (48.12 %) -0.5% BM_ZFlat/13 31518 31987 333.3MB/s c (42.40 %) -1.5% BM_ZFlat/14 10598 10827 328.6MB/s lsp (48.37 %) -2.1% BM_ZFlat/15 1782243 1802728 546.5MB/s xls (41.23 %) -1.1% BM_ZFlat/16 526 539 355.0MB/s xls_200 (78.00 %) -2.4% BM_ZFlat/17 598141 597311 822.1MB/s bin (18.11 %) +0.1% BM_ZFlat/18 121 120 1.6GB/s bin_200 (7.50 %) +0.8% BM_ZFlat/19 109981 112173 326.0MB/s sum (48.96 %) -2.0% BM_ZFlat/20 14355 14575 277.4MB/s man (59.36 %) -1.5% Sum of all benchmarks 33882722 33879325 +0.0% Sandy Bridge (64-bit, opt): Benchmark Base (ns) New (ns) Improvement -------------------------------------------------------------------------------------- BM_UFlat/0 43764 41600 2.3GB/s html +5.2% BM_UFlat/1 517990 507058 1.3GB/s urls +2.2% BM_UFlat/2 6625 5529 20.8GB/s jpg +19.8% BM_UFlat/3 154 155 1.2GB/s jpg_200 -0.6% BM_UFlat/4 12795 11747 8.1GB/s pdf +8.9% BM_UFlat/5 200335 193413 2.0GB/s html4 +3.6% BM_UFlat/6 156574 156426 929.2MB/s txt1 +0.1% BM_UFlat/7 137574 137464 870.4MB/s txt2 +0.1% BM_UFlat/8 422551 421603 967.4MB/s txt3 +0.2% BM_UFlat/9 577749 578985 795.6MB/s txt4 -0.2% BM_UFlat/10 42329 39362 2.8GB/s pb +7.5% BM_UFlat/11 170615 169751 1037.9MB/s gaviota +0.5% BM_UFlat/12 12800 12719 1.8GB/s cp +0.6% BM_UFlat/13 6585 6579 1.6GB/s c +0.1% BM_UFlat/14 2066 2044 1.7GB/s lsp +1.1% BM_UFlat/15 750861 746911 1.3GB/s xls +0.5% BM_UFlat/16 188 192 996.0MB/s xls_200 -2.1% BM_UFlat/17 271622 264333 1.8GB/s bin +2.8% BM_UFlat/18 208 207 923.6MB/s bin_200 +0.5% BM_UFlat/19 24667 24845 1.4GB/s sum -0.7% BM_UFlat/20 2663 2662 1.5GB/s man +0.0% BM_ZFlat/0 115173 115624 846.5MB/s html (22.31 %) -0.4% BM_ZFlat/1 1530331 1537769 436.5MB/s urls (47.77 %) -0.5% BM_ZFlat/2 17503 17013 6.8GB/s jpg (99.95 %) +2.9% BM_ZFlat/3 385 385 496.3MB/s jpg_200 (73.00 %) +0.0% BM_ZFlat/4 61753 61540 1.6GB/s pdf (81.85 %) +0.3% BM_ZFlat/5 484806 483356 810.1MB/s html4 (22.51 %) +0.3% BM_ZFlat/6 464143 467609 310.9MB/s txt1 (57.87 %) -0.7% BM_ZFlat/7 410315 413319 289.5MB/s txt2 (61.93 %) -0.7% BM_ZFlat/8 1244082 1249381 326.5MB/s txt3 (54.92 %) -0.4% BM_ZFlat/9 1696914 1709685 269.4MB/s txt4 (66.22 %) -0.7% BM_ZFlat/10 104148 103372 1096.7MB/s pb (19.64 %) +0.8% BM_ZFlat/11 363522 359722 489.8MB/s gaviota (37.72 %) +1.1% BM_ZFlat/12 47021 50095 469.3MB/s cp (48.12 %) -6.1% BM_ZFlat/13 16888 16985 627.4MB/s c (42.40 %) -0.6% BM_ZFlat/14 5496 5469 650.3MB/s lsp (48.37 %) +0.5% BM_ZFlat/15 1460713 1448760 679.5MB/s xls (41.23 %) +0.8% BM_ZFlat/16 387 393 486.8MB/s xls_200 (78.00 %) -1.5% BM_ZFlat/17 457654 451462 1086.6MB/s bin (18.11 %) +1.4% BM_ZFlat/18 97 87 2.1GB/s bin_200 (7.50 %) +11.5% BM_ZFlat/19 77904 80924 451.7MB/s sum (48.96 %) -3.7% BM_ZFlat/20 7648 7663 527.1MB/s man (59.36 %) -0.2% Sum of all benchmarks 25493635 25482069 +0.0% A=dehao R=sesse
2015-06-22 13:41:30 +00:00
if (UNALIGNED_LOAD64(s2) == UNALIGNED_LOAD64(s1 + matched)) {
s2 += 8;
matched += 8;
} else {
// On current (mid-2008) Opteron models there is a 3% more
// efficient code sequence to find the first non-matching byte.
// However, what follows is ~10% better on Intel Core 2 and newer,
// and we expect AMD's bsf instruction to improve.
uint64 x = UNALIGNED_LOAD64(s2) ^ UNALIGNED_LOAD64(s1 + matched);
int matching_bits = Bits::FindLSBSetNonZero64(x);
matched += matching_bits >> 3;
return matched;
}
}
while (PREDICT_TRUE(s2 < s2_limit)) {
Change a few branch annotations that profiling found to be wrong. Overall performance is neutral or slightly positive. Westmere (64-bit, opt): Benchmark Base (ns) New (ns) Improvement -------------------------------------------------------------------------------------- BM_UFlat/0 73798 71464 1.3GB/s html +3.3% BM_UFlat/1 715223 704318 953.5MB/s urls +1.5% BM_UFlat/2 8137 8871 13.0GB/s jpg -8.3% BM_UFlat/3 200 204 935.5MB/s jpg_200 -2.0% BM_UFlat/4 21627 21281 4.5GB/s pdf +1.6% BM_UFlat/5 302806 290350 1.3GB/s html4 +4.3% BM_UFlat/6 218920 219017 664.1MB/s txt1 -0.0% BM_UFlat/7 190437 191212 626.1MB/s txt2 -0.4% BM_UFlat/8 584192 580484 703.4MB/s txt3 +0.6% BM_UFlat/9 776537 779055 591.6MB/s txt4 -0.3% BM_UFlat/10 76056 72606 1.5GB/s pb +4.8% BM_UFlat/11 235962 239043 737.4MB/s gaviota -1.3% BM_UFlat/12 28049 28000 840.1MB/s cp +0.2% BM_UFlat/13 12225 12021 886.9MB/s c +1.7% BM_UFlat/14 3362 3544 1004.0MB/s lsp -5.1% BM_UFlat/15 937015 939206 1048.9MB/s xls -0.2% BM_UFlat/16 236 233 823.1MB/s xls_200 +1.3% BM_UFlat/17 373170 361947 1.3GB/s bin +3.1% BM_UFlat/18 264 264 725.5MB/s bin_200 +0.0% BM_UFlat/19 42834 43577 839.2MB/s sum -1.7% BM_UFlat/20 4770 4736 853.6MB/s man +0.7% BM_UValidate/0 39671 39944 2.4GB/s html -0.7% BM_UValidate/1 443391 443391 1.5GB/s urls +0.0% BM_UValidate/2 163 163 703.3GB/s jpg +0.0% BM_UValidate/3 113 112 1.7GB/s jpg_200 +0.9% BM_UValidate/4 7555 7608 12.6GB/s pdf -0.7% BM_ZFlat/0 157616 157568 621.5MB/s html (22.31 %) +0.0% BM_ZFlat/1 1997290 2014486 333.4MB/s urls (47.77 %) -0.9% BM_ZFlat/2 23035 22237 5.2GB/s jpg (99.95 %) +3.6% BM_ZFlat/3 539 540 354.5MB/s jpg_200 (73.00 %) -0.2% BM_ZFlat/4 80709 81369 1.2GB/s pdf (81.85 %) -0.8% BM_ZFlat/5 639059 639220 613.0MB/s html4 (22.51 %) -0.0% BM_ZFlat/6 577203 583370 249.3MB/s txt1 (57.87 %) -1.1% BM_ZFlat/7 510887 516094 232.0MB/s txt2 (61.93 %) -1.0% BM_ZFlat/8 1535843 1556973 262.2MB/s txt3 (54.92 %) -1.4% BM_ZFlat/9 2070068 2102380 219.3MB/s txt4 (66.22 %) -1.5% BM_ZFlat/10 152396 152148 745.5MB/s pb (19.64 %) +0.2% BM_ZFlat/11 447367 445859 395.4MB/s gaviota (37.72 %) +0.3% BM_ZFlat/12 76375 76797 306.3MB/s cp (48.12 %) -0.5% BM_ZFlat/13 31518 31987 333.3MB/s c (42.40 %) -1.5% BM_ZFlat/14 10598 10827 328.6MB/s lsp (48.37 %) -2.1% BM_ZFlat/15 1782243 1802728 546.5MB/s xls (41.23 %) -1.1% BM_ZFlat/16 526 539 355.0MB/s xls_200 (78.00 %) -2.4% BM_ZFlat/17 598141 597311 822.1MB/s bin (18.11 %) +0.1% BM_ZFlat/18 121 120 1.6GB/s bin_200 (7.50 %) +0.8% BM_ZFlat/19 109981 112173 326.0MB/s sum (48.96 %) -2.0% BM_ZFlat/20 14355 14575 277.4MB/s man (59.36 %) -1.5% Sum of all benchmarks 33882722 33879325 +0.0% Sandy Bridge (64-bit, opt): Benchmark Base (ns) New (ns) Improvement -------------------------------------------------------------------------------------- BM_UFlat/0 43764 41600 2.3GB/s html +5.2% BM_UFlat/1 517990 507058 1.3GB/s urls +2.2% BM_UFlat/2 6625 5529 20.8GB/s jpg +19.8% BM_UFlat/3 154 155 1.2GB/s jpg_200 -0.6% BM_UFlat/4 12795 11747 8.1GB/s pdf +8.9% BM_UFlat/5 200335 193413 2.0GB/s html4 +3.6% BM_UFlat/6 156574 156426 929.2MB/s txt1 +0.1% BM_UFlat/7 137574 137464 870.4MB/s txt2 +0.1% BM_UFlat/8 422551 421603 967.4MB/s txt3 +0.2% BM_UFlat/9 577749 578985 795.6MB/s txt4 -0.2% BM_UFlat/10 42329 39362 2.8GB/s pb +7.5% BM_UFlat/11 170615 169751 1037.9MB/s gaviota +0.5% BM_UFlat/12 12800 12719 1.8GB/s cp +0.6% BM_UFlat/13 6585 6579 1.6GB/s c +0.1% BM_UFlat/14 2066 2044 1.7GB/s lsp +1.1% BM_UFlat/15 750861 746911 1.3GB/s xls +0.5% BM_UFlat/16 188 192 996.0MB/s xls_200 -2.1% BM_UFlat/17 271622 264333 1.8GB/s bin +2.8% BM_UFlat/18 208 207 923.6MB/s bin_200 +0.5% BM_UFlat/19 24667 24845 1.4GB/s sum -0.7% BM_UFlat/20 2663 2662 1.5GB/s man +0.0% BM_ZFlat/0 115173 115624 846.5MB/s html (22.31 %) -0.4% BM_ZFlat/1 1530331 1537769 436.5MB/s urls (47.77 %) -0.5% BM_ZFlat/2 17503 17013 6.8GB/s jpg (99.95 %) +2.9% BM_ZFlat/3 385 385 496.3MB/s jpg_200 (73.00 %) +0.0% BM_ZFlat/4 61753 61540 1.6GB/s pdf (81.85 %) +0.3% BM_ZFlat/5 484806 483356 810.1MB/s html4 (22.51 %) +0.3% BM_ZFlat/6 464143 467609 310.9MB/s txt1 (57.87 %) -0.7% BM_ZFlat/7 410315 413319 289.5MB/s txt2 (61.93 %) -0.7% BM_ZFlat/8 1244082 1249381 326.5MB/s txt3 (54.92 %) -0.4% BM_ZFlat/9 1696914 1709685 269.4MB/s txt4 (66.22 %) -0.7% BM_ZFlat/10 104148 103372 1096.7MB/s pb (19.64 %) +0.8% BM_ZFlat/11 363522 359722 489.8MB/s gaviota (37.72 %) +1.1% BM_ZFlat/12 47021 50095 469.3MB/s cp (48.12 %) -6.1% BM_ZFlat/13 16888 16985 627.4MB/s c (42.40 %) -0.6% BM_ZFlat/14 5496 5469 650.3MB/s lsp (48.37 %) +0.5% BM_ZFlat/15 1460713 1448760 679.5MB/s xls (41.23 %) +0.8% BM_ZFlat/16 387 393 486.8MB/s xls_200 (78.00 %) -1.5% BM_ZFlat/17 457654 451462 1086.6MB/s bin (18.11 %) +1.4% BM_ZFlat/18 97 87 2.1GB/s bin_200 (7.50 %) +11.5% BM_ZFlat/19 77904 80924 451.7MB/s sum (48.96 %) -3.7% BM_ZFlat/20 7648 7663 527.1MB/s man (59.36 %) -0.2% Sum of all benchmarks 25493635 25482069 +0.0% A=dehao R=sesse
2015-06-22 13:41:30 +00:00
if (s1[matched] == *s2) {
++s2;
++matched;
} else {
return matched;
}
}
return matched;
}
#else
static inline int FindMatchLength(const char* s1,
const char* s2,
const char* s2_limit) {
// Implementation based on the x86-64 version, above.
assert(s2_limit >= s2);
int matched = 0;
while (s2 <= s2_limit - 4 &&
UNALIGNED_LOAD32(s2) == UNALIGNED_LOAD32(s1 + matched)) {
s2 += 4;
matched += 4;
}
if (LittleEndian::IsLittleEndian() && s2 <= s2_limit - 4) {
uint32 x = UNALIGNED_LOAD32(s2) ^ UNALIGNED_LOAD32(s1 + matched);
int matching_bits = Bits::FindLSBSetNonZero(x);
matched += matching_bits >> 3;
} else {
while ((s2 < s2_limit) && (s1[matched] == *s2)) {
++s2;
++matched;
}
}
return matched;
}
#endif
} // end namespace internal
} // end namespace snappy
#endif // THIRD_PARTY_SNAPPY_SNAPPY_INTERNAL_H_