Add compression size reporting hooks.

Also, force inlining util::compression::Sample().

The inlining change is necessary. Without it even with FDO+LIPO the call
doesn't get inlined and uses 4 registers to construct parameters (which
won't be used in the common case). In some of the more compute-bound
tests that causes extra spills and significant overhead (even if
call is sufficiently long).
For example, with inlining:
BM_UFlat/0         32.7µs ± 1%    33.1µs ± 1%  +1.41%
without:
BM_UFlat/0         32.7µs ± 1%    37.7µs ± 1%  +15.29%
This commit is contained in:
skanev 2017-02-01 08:34:26 -08:00 committed by Victor Costan
parent 626e1b9faa
commit d3c6d20d0a

View file

@ -527,6 +527,10 @@ char* CompressFragment(const char* input,
} }
} // end namespace internal } // end namespace internal
// Called back at avery compression call to trace parameters and sizes.
static inline void Report(const char *algorithm, size_t compressed_size,
size_t uncompressed_size) {}
// Signature of output types needed by decompression code. // Signature of output types needed by decompression code.
// The decompression code is templatized on a type that obeys this // The decompression code is templatized on a type that obeys this
// signature so that we do not pay virtual function call overhead in // signature so that we do not pay virtual function call overhead in
@ -786,13 +790,18 @@ static bool InternalUncompress(Source* r, Writer* writer) {
SnappyDecompressor decompressor(r); SnappyDecompressor decompressor(r);
uint32 uncompressed_len = 0; uint32 uncompressed_len = 0;
if (!decompressor.ReadUncompressedLength(&uncompressed_len)) return false; if (!decompressor.ReadUncompressedLength(&uncompressed_len)) return false;
return InternalUncompressAllTags(&decompressor, writer, uncompressed_len);
return InternalUncompressAllTags(&decompressor, writer, r->Available(),
uncompressed_len);
} }
template <typename Writer> template <typename Writer>
static bool InternalUncompressAllTags(SnappyDecompressor* decompressor, static bool InternalUncompressAllTags(SnappyDecompressor* decompressor,
Writer* writer, Writer* writer,
uint32 compressed_len,
uint32 uncompressed_len) { uint32 uncompressed_len) {
Report("snappy_uncompress", compressed_len, uncompressed_len);
writer->SetExpectedLength(uncompressed_len); writer->SetExpectedLength(uncompressed_len);
// Process the entire input // Process the entire input
@ -809,6 +818,7 @@ bool GetUncompressedLength(Source* source, uint32* result) {
size_t Compress(Source* reader, Sink* writer) { size_t Compress(Source* reader, Sink* writer) {
size_t written = 0; size_t written = 0;
size_t N = reader->Available(); size_t N = reader->Available();
const size_t uncompressed_size = N;
char ulength[Varint::kMax32]; char ulength[Varint::kMax32];
char* p = Varint::Encode32(ulength, N); char* p = Varint::Encode32(ulength, N);
writer->Append(ulength, p-ulength); writer->Append(ulength, p-ulength);
@ -881,6 +891,8 @@ size_t Compress(Source* reader, Sink* writer) {
reader->Skip(pending_advance); reader->Skip(pending_advance);
} }
Report("snappy_compress", written, uncompressed_size);
delete[] scratch; delete[] scratch;
delete[] scratch_output; delete[] scratch_output;
@ -1446,18 +1458,20 @@ bool Uncompress(Source* compressed, Sink* uncompressed) {
char* buf = uncompressed->GetAppendBufferVariable( char* buf = uncompressed->GetAppendBufferVariable(
1, uncompressed_len, &c, 1, &allocated_size); 1, uncompressed_len, &c, 1, &allocated_size);
const size_t compressed_len = compressed->Available();
// If we can get a flat buffer, then use it, otherwise do block by block // If we can get a flat buffer, then use it, otherwise do block by block
// uncompression // uncompression
if (allocated_size >= uncompressed_len) { if (allocated_size >= uncompressed_len) {
SnappyArrayWriter writer(buf); SnappyArrayWriter writer(buf);
bool result = InternalUncompressAllTags( bool result = InternalUncompressAllTags(&decompressor, &writer,
&decompressor, &writer, uncompressed_len); compressed_len, uncompressed_len);
uncompressed->Append(buf, writer.Produced()); uncompressed->Append(buf, writer.Produced());
return result; return result;
} else { } else {
SnappySinkAllocator allocator(uncompressed); SnappySinkAllocator allocator(uncompressed);
SnappyScatteredWriter<SnappySinkAllocator> writer(allocator); SnappyScatteredWriter<SnappySinkAllocator> writer(allocator);
return InternalUncompressAllTags(&decompressor, &writer, uncompressed_len); return InternalUncompressAllTags(&decompressor, &writer, compressed_len,
uncompressed_len);
} }
} }