Commit Graph

282 Commits

Author SHA1 Message Date
Victor Costan
402d88812c Fixup for adding the third_party/{benchmark, googletest} submodules. (#115) 2020-12-15 12:01:28 -08:00
Victor Costan
6badb0a261 Merge pull request #114 from cmumford:werror-only-clang
PiperOrigin-RevId: 347660305
2020-12-15 19:49:13 +00:00
Chris Mumford
bc53daa7be Fixed endif clause. 2020-12-15 11:19:53 -08:00
Chris Mumford
e9a6a08439 Matching clang. 2020-12-15 11:17:28 -08:00
Chris Mumford
955a5dd1b3 Building with -Werror only with clang.
gcc was unable to inline a function call, which caused a build
failure due to `-Wall -Werror`.

The build error was:

```
../snappy.cc:292:76: error: ignoring attributes on template argument ‘__m128i’ [-Werror=ignored-attributes]
  292 | static inline std::pair<__m128i /* pattern */, __m128i /* reshuffle_mask */>
      |                                                                            ^
../snappy.cc:292:76: error: ignoring attributes on template argument ‘__m128i’ [-Werror=ignored-attributes]
cc1plus: all warnings being treated as errors
```
2020-12-15 11:02:17 -08:00
Chris Mumford
42d1dd7ea3 Fix CHECK_EQ to call ok() instead of CheckSuccess().
CheckSuccess was removed in e1e91ee464.

PiperOrigin-RevId: 347625874
2020-12-15 09:16:39 -08:00
Victor Costan
eaaa0ed0ca Fixup for adding the third_party/{benchmark, googletest} submodules. (#111) 2020-12-15 08:49:01 -08:00
Victor Costan
e1e91ee464 Rework file:: stubs.
PiperOrigin-RevId: 347541488
2020-12-15 06:21:47 +00:00
Victor Costan
6aa79cb471 Wrap snappy_unittest in an anonymous namespace and remove static from functions.
PiperOrigin-RevId: 347541028
2020-12-15 06:18:35 +00:00
Victor Costan
bae9f9bef8 Fixup for adding the third_party/{benchmark, googletest} submodules. (#110) 2020-12-14 20:27:33 -08:00
Victor Costan
5f913be04e Fix unused local variable warnings.
This will not change the compilation output.

PiperOrigin-RevId: 347525836
2020-12-15 04:14:46 +00:00
Victor Costan
549685a598 Remove custom testing and benchmarking code.
Snappy includes a testing framework, which implements a subset of the
Google Test API, and can be used when Google Test is not available.
Snappy also includes a micro-benchmark framework, which implements an
old version of the Google Benchmark API.

This CL replaces the custom test and micro-benchmark frameworks with
google/googletest and google/benchmark. The code is vendored in
third_party/ via git submodules. The setup is similar to google/crc32c
and google/leveldb.

This CL also updates the benchmarking code to the modern Google
Benchmark API.

Benchmark results are expected to be more precise, as the old framework
ran each benchmark with a fixed number of iterations, whereas Google
Benchmark keeps iterating until the noise is low.

PiperOrigin-RevId: 347456142
2020-12-14 21:27:31 +00:00
Chris Mumford
11f9a77a2f Add Travis-CI build status badge to README.md.
PiperOrigin-RevId: 347402877
2020-12-14 09:40:22 -08:00
Victor Costan
49540965a3 Update Travis CI config.
PiperOrigin-RevId: 347397797
2020-12-14 09:11:46 -08:00
Victor Costan
8995ffabb9 Replace #pragma nounroll with equivalent used elsewhere.
PiperOrigin-RevId: 347341130
2020-12-14 09:59:34 +00:00
Victor Costan
d1daa83044 Remove inline qualifier from static variables.
This feature requires C++17. Fortunately, inline is useful for header declarations, which may be included in multiple compilation units. The declarations modified by this CL occur in a single compilation unit.

PiperOrigin-RevId: 347338760
2020-12-14 09:59:23 +00:00
Snappy Team
3b571656fa 1) Improve the lookup table data to require less instructions to extract the necessary data. We now store len - offset in a signed int16, this happens to remove masking offset in the calculations and the calculations that need to be done precisely give the flags that we need for testing correctness.
2) Replace offset extraction with a lookup mask. This is less uops and is needed because we need to special case type 3 to always return 0 as to properly trigger the fallback.
3) Unroll the loop twice, this removes some loop-condition checks AND it improves the generated assembly. The loop variables tend to end up in a different register requiring mov's having two consecutive copies allows the elision of the mov's.

PiperOrigin-RevId: 346663328
2020-12-14 02:48:03 +00:00
Shahriar Rouf
a9730ed505 Optimize zippy decompression by making IncrementalCopy faster.
When SSSE3 is available:
- Use PSHUFB (_mm_shuffle_epi8) to handle pattern size 1 to 15 (previously it handled size 1 to 7).
- This enables us to do 16 byte copies instead of 8 bytes copies because we know that the pattern size >= 16.
- Use shuffle-reshuffle strategy to generate the next pattern after loading the initial pattern. This enables us to write 4 conditionals (similar to when pattern size >= 16) which would allow FDO to layout the code with respect to actual probabilities of each length.
- The PSHUFB masks are now generated programmatically at compile-time.

When SSSE3 is unavailable:
- No change.

In both cases:
- assert(op < op_limit) in IncrementalCopy so that we can check 'op_limit <= buf_limit - 15' instead of 'op_limit <= buf_limit - 16'. All existing call sites of IncrementalCopy guarantee this.

'bin' case is notably >20% faster because it has many repeated character patterns (i.e. pattern_size = 1).

PiperOrigin-RevId: 346454471
2020-12-14 02:47:49 +00:00
Snappy Team
56c2c247d0 Internal change
PiperOrigin-RevId: 345360683
2020-12-03 22:52:52 +00:00
Shahriar Rouf
a94be58e65 Optimize zippy decompression by making IncrementalCopy faster.
When SSSE3 is available:
- Use PSHUFB (_mm_shuffle_epi8) to handle pattern size 1 to 15 (previously it handled size 1 to 7).
- This enables us to do 16 byte copies instead of 8 bytes copies because we know that the pattern size >= 16.
- Use shuffle-reshuffle strategy to generate the next pattern after loading the initial pattern. This enables us to write 4 conditionals (similar to when pattern size >= 16) which would allow FDO to layout the code with respect to actual probabilities of each length.
- The PSHUFB masks are now generated programmatically at compile-time.

When SSSE3 is unavailable:
- No change.

In both cases:
- assert(op < op_limit) in IncrementalCopy so that we can check 'op_limit <= buf_limit - 15' instead of 'op_limit <= buf_limit - 16'. All existing call sites of IncrementalCopy guarantee this.

'bin' case is notably >20% faster because it has many repeated character patterns (i.e. pattern_size = 1).

PiperOrigin-RevId: 345340892
2020-12-03 22:52:41 +00:00
Snappy Team
01a566f825 Fix opensource version
PiperOrigin-RevId: 343272548
2020-11-19 17:06:26 +00:00
Snappy Team
616b8229b6 Add LZ4 as a benchmark option. Snappy is starting to look really good compared to LZ4. LZ4 is considered the fastest solution by many on internet. We now see that Snappy is actually becoming very competitive with compression a little faster and decompression slower but certainly not terribly slower.
PiperOrigin-RevId: 343140860
2020-11-18 23:22:04 +00:00
Snappy Team
e4a6e97b91 Extend validate benchmarks over all types and also add a medley for validation.
I also made the compression happen only once per benchmark. This way we get a cleaner measurement of #branch-misses using "perf stat". Compression suffers naturally from a large number of branch misses which was polluting the measurements.

This showed that with the new decompression the branch misses is actually much lower then initially reported, only .2% and very stable, ie. doesn't really fluctuate with how you execute the benchmarks.

PiperOrigin-RevId: 342628576
2020-11-18 23:21:55 +00:00
Snappy Team
719bed0ae2 Bug fix. Error on 0 offset copies.
PiperOrigin-RevId: 342447553
2020-11-18 23:21:47 +00:00
Snappy Team
289c8a3c0a Make zippy decompression branchless
PiperOrigin-RevId: 342423961
2020-11-18 23:21:38 +00:00
Snappy Team
3bfa265a04 Revert zippy optimization that causes heap buffer overflows.
PiperOrigin-RevId: 342283314
2020-11-18 23:21:30 +00:00
Shahriar Rouf
4d2dc9dcbb Optimize zippy unzipping by upto >10% by making IncrementalCopy faster.
When SSSE3 is available:
- Use PSHUFB (_mm_shuffle_epi8) to handle pattern size 1 to 15 (previously it handled size 1 to 7).
- This enables us to do 16 byte copies instead of 8 bytes copies because we know that the pattern size >= 16.
- Use shuffle-reshuffle strategy to generate the next pattern after loading the initial pattern. This enables us to write 4 conditionals (similar to when pattern size >= 16) which would allow FDO to layout the code with respect to actual probabilities of each length.
- The PSHUFB masks are now generated programmatically at compile-time.

When SSSE3 is unavailable:
- No change.

In both cases:
- assert(op < op_limit) in IncrementalCopy so that we can check 'op_limit <= buf_limit - 15' instead of 'op_limit <= buf_limit - 16'. All existing call sites of IncrementalCopy guarantee this.

PiperOrigin-RevId: 342267037
2020-11-18 23:21:21 +00:00
Snappy Team
11e5165b98 Add a benchmark that decreased the branch prediction memorization by increasing the amount of independent branches executed per benchmark iteration.
PiperOrigin-RevId: 342242843
2020-11-18 23:21:12 +00:00
Luca Versari
6835abd953 Change hash function for Compress.
((a*b)>>18) & mask has higher throughput than (a*b)>>shift, and produces the
same results when the hash table size is 2**14. In other cases, the hash
function is still good, but it's not as necessary for that to be the case as
the input is small anyway. This speeds up in encoding, especially in cases
where hashing is a significant part of the encoding critical path (small or
uncompressible files).

PiperOrigin-RevId: 341498741
2020-11-18 23:20:58 +00:00
Victor Costan
368b01c8dd Merge pull request #107 from jsteemann:bug-fix/fix-compile-warning
PiperOrigin-RevId: 340505526
2020-11-03 20:51:55 +00:00
Snappy Team
1ce58af28e Fix the use of op + len when op is nullptr and len is non-zero.
See https://reviews.llvm.org/D67122 for some discussion of why this can matter.
I don't think this should have any noticeable effect on performance.

PiperOrigin-RevId: 340255083
2020-11-03 20:30:24 +00:00
Luca Versari
0b990db2b8 Run clang-format
PiperOrigin-RevId: 339897712
2020-11-03 20:30:11 +00:00
jsteemann
cb2b3c7ec6 fix compile warnings due to missing override specifiers
When building Snappy with compiler option `-Wsuggest-override` set
via the CMAKE_CXX_FLAGS, compilation produces warnings in
`snappy-sinksource.h`:

```
In file included from ./snappy-fork/snappy-sinksource.cc:32:
./snappy-fork/snappy-sinksource.h:150:18: error: ‘virtual size_t snappy::ByteArraySource::Available() const’ can be marked override [-Werror=suggest-override]
  150 |   virtual size_t Available() const;
      |                  ^~~~~~~~~
./snappy-fork/snappy-sinksource.h:151:23: error: ‘virtual const char* snappy::ByteArraySource::Peek(size_t*)’ can be marked override [-Werror=suggest-override]
  151 |   virtual const char* Peek(size_t* len);
      |                       ^~~~
./snappy-fork/snappy-sinksource.h:152:16: error: ‘virtual void snappy::ByteArraySource::Skip(size_t)’ can be marked override [-Werror=suggest-override]
  152 |   virtual void Skip(size_t n);
      |                ^~~~
./snappy-fork/snappy-sinksource.h:163:16: error: ‘virtual void snappy::UncheckedByteArraySink::Append(const char*, size_t)’ can be marked override [-Werror=suggest-override]
  163 |   virtual void Append(const char* data, size_t n);
      |                ^~~~~~
./snappy-fork/snappy-sinksource.h:164:17: error: ‘virtual char* snappy::UncheckedByteArraySink::GetAppendBuffer(size_t, char*)’ can be marked override [-Werror=suggest-override]
  164 |   virtual char* GetAppendBuffer(size_t len, char* scratch);
      |                 ^~~~~~~~~~~~~~~
./snappy-fork/snappy-sinksource.h:165:17: error: ‘virtual char* snappy::UncheckedByteArraySink::GetAppendBufferVariable(size_t, size_t, char*, size_t, size_t*)’ can be marked override [-Werror=suggest-override]
  165 |   virtual char* GetAppendBufferVariable(
      |                 ^~~~~~~~~~~~~~~~~~~~~~~
./snappy-fork/snappy-sinksource.h:168:16: error: ‘virtual void snappy::UncheckedByteArraySink::AppendAndTakeOwnership(char*, size_t, void (*)(void*, const char*, size_t), void*)’ can be marked override [-Werror=suggest-override]
  168 |   virtual void AppendAndTakeOwnership(
      |                ^~~~~~~~~~~~~~~~~~~~~~
cc1plus: all warnings being treated as errors
```

This PR adds the missing override specifiers to the sink
implementations, so compilation works fine again.

Tested it with g++-9.3 and g++-10.2.

Compatibility note:
Override specifiers were introduced with C++11, which Snappy seems
to effectively require, at least according to its CMakeLists.txt file
and due to the usage of some C++11-only STL types in its tests.
2020-10-29 21:50:50 +01:00
Chris Kennelly
7ffaf77cf4 Replace ARCH_K8 with __x86_64__.
PiperOrigin-RevId: 321389098
2020-10-07 21:12:27 +00:00
Snappy Team
4dd277fed4 Replace the division with a constant table in IncrementalCopy
PiperOrigin-RevId: 320686580
2020-07-11 01:54:52 +00:00
Snappy Team
f16eda3466 Correct uninitialized variable.
PiperOrigin-RevId: 312741918
2020-06-01 23:46:44 +00:00
Victor Costan
837f38b3e0 Revise stubs for ARCH_{K8,PPC,ARM}.
* ARCH_K8 and ARCH_ARM now work correctly on MSVC.
* ARCH_PPC now uses the same macro as tcmalloc.

Microsoft documentation:
https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros?view=vs-2019

PowerPC documentation:
http://openpowerfoundation.org/wp-content/uploads/resources/leabi/content/dbdoclet.50655243_75216.html

PiperOrigin-RevId: 310160787
2020-05-06 16:07:47 +00:00
Victor Costan
e1353b9fa8 Remove ARCH_* guards around Bits::FindLSBSetNonZero64().
Bits::FindLSBSetNonZero64() is now available unconditionally, and it
should be easier to reason about the code included in each build
configuration.

This reduces the amount of conditional compiling going on, which makes
it easier to reason about what stubs are a used in each build
configuration.

The guards were added to work around the fact that MSVC has a
_BitScanForward64() intrinsic, but the intrinsic is only implemented on
64-bit targets, and causes a compilation error on 32-bit targets errors.
By contrast, Clang and GCC support __builtin_ctzll() everywhere, and
implement it with varying efficiency.

This CL reworks the conditional compilation directives so that
Bits::FindLSBSetNonZero64() uses the _BitScanForward64() intrinsic on
MSVC when available, and the portable implementation otherwise.
PiperOrigin-RevId: 310007748
2020-05-05 20:18:12 +00:00
Victor Costan
c98344f626 Fix Clang/GCC compilation warnings.
This makes it easier to adopt snappy in other projects.

PiperOrigin-RevId: 309958249
2020-05-05 16:15:02 +00:00
Victor Costan
113cd97ab3 Tighten types on a few for loops.
* Replace post-increment with pre-increment in for loops.
* Replace unsigned int counters with precise types, like uint8_t.
* Switch to C++11 iterating loops when possible.

PiperOrigin-RevId: 309724233
2020-05-04 12:32:00 +00:00
Victor Costan
abde3abb1f Fix Travis CI build.
PiperOrigin-RevId: 309143110
2020-04-30 02:09:07 +00:00
Victor Costan
e6506681fa Fix accidental double std:: qualifiers.
PiperOrigin-RevId: 309136120
2020-04-30 01:19:26 +00:00
Victor Costan
63620c06d2 Add some std:: qualifiers to types and functions.
PiperOrigin-RevId: 309110343
2020-04-29 22:31:55 +00:00
Victor Costan
5417da69b7 Switch from C headers to C++ headers.
This CL makes the following substitutions.

* assert.h -> cassert
* math.h -> cmath
* stdarg.h -> cstdarg
* stdio.h -> cstdio
* stdlib.h -> cstdlib
* string.h -> cstring

stddef.h and stdint.h are not migrated to C++ headers.

PiperOrigin-RevId: 309074805
2020-04-29 19:38:03 +00:00
Victor Costan
251d935d50 Remove #include <string> from snappy-stubs-public.h.
The header hasn't been needed since the removal of the snappy::string
alias to std::string.

PiperOrigin-RevId: 306446542
2020-04-14 16:50:30 +00:00
Victor Costan
4f195aee43 Remove mismatched #endif.
PiperOrigin-RevId: 306345559
2020-04-14 00:38:04 +00:00
Victor Costan
041c608086 Remove platform-dependent code for unaligned loads/stores.
Snappy issues multi-byte (16/32/64-bit) loads and stores that are not
aligned, meaning the addresses are 16/32/64-bit multiples. This is
accomplished using two methods:

1) The portable method allocates a uint{16,32,64}_t on the stack, and
std::memcpy()s the bytes into/from the integer. This method relies on
well-defined behaviori (std::memcpy() works on all valid pointers,
fixed-width unsigned integer types use a pure binary representation and
therefore have no invalid values), and should compile to valid code on
all platforms.

2) The fast method reinterpret_casts the address to a pointer to a
uint{16,32,64}_t and dereferences the pointer. This is expected to
compile to one hardware instruction (mov on x86, ldr/str on arm). The
caveat is that the reinterpret_cast is undefined behavior (UB) unless the
address happened to be a valid uint{16,32,64}_t pointer. The UB shows up
as follows.
* On architectures that don't have hardware instructions for unaligned
  loads / stores, the pointer access can trigger a hardware exceptions.
  This is mitigated by #ifdef blocks that attempt to restrict the fast
  method to platforms that support it.
* On architectures that have separate instructions for aligned and
  unaligned access, the compiler may need an explicit hint to emit the
  hardware instruction for unaligned access. This is accomplished on
  Clang and GCC by wrapping the pointers into structs tagged with
  __attribute__((__packed__)).

This CL removes the fast method. Fortunately, compilers have advanced
enough that the portable method gets compiled down to the same
instructions as the fast method, without the need for the caveats
explained above. Specifically, modern Clang, GCC and MSVC optimize
std::memcpy() to a single instruction (mov / ldr / str). A test case
proving this can be seen at https://godbolt.org/z/gZg2Fk
PiperOrigin-RevId: 306342728
2020-04-14 00:22:20 +00:00
Victor Costan
27ff130ff9 Remove platform-dependent code for little-endian loads and stores.
The platform-independent code that breaks down the loads and stores into
byte-level operations is optimized into single instructions (mov or
ldr/str) and instruction pairs (mov+bswap or ldr/str+rev) by recent
versions of Clang and GCC. Tested at https://godbolt.org/z/2BQP-o

PiperOrigin-RevId: 306321608
2020-04-13 22:30:59 +00:00
Victor Costan
a4cdb5d133 Introduce SNAPPY_ATTRIBUTE_ALWAYS_INLINE.
An internal CL started using ABSL_ATTRIBUTE_ALWAYS_INLINE
from Abseil. This CL introduces equivalent functionality as
SNAPPY_ALWAYS_INLINE.

PiperOrigin-RevId: 306289650
2020-04-13 19:51:05 +00:00
Victor Costan
231b8be076 Migrate to standard integral types.
The following changes are done via find/replace.
* int8 -> int8_t
* int16 -> int16_t
* int32 -> int32_t
* int64 -> int64_t

The aliases were removed from snappy-stubs-public.h.

PiperOrigin-RevId: 306141557
2020-04-12 20:10:03 +00:00