Optimize zstd compression

reuse the same context for zstd compression. One context should be used
per compression thread for optimal performance. Discussion and
reccomendations can be found at go/android-hw-compression-vendor

Results (level 3 compression)
full ota on raven with optimizations:  1191.304 seconds
without optimizations:  1461.854 seconds

compression ratio remains unchanged and merge time difference are
negligible ~1% delta (probably just noise)

Test: ota_from_target_files, update_device.py
Change-Id: I3feede9f1f119874e369c54b29c594475fbf7376
This commit is contained in:
Daniel Zheng 2023-08-09 13:48:08 -07:00
parent de6e446efa
commit 03acfdbeb6

View file

@ -18,6 +18,7 @@
#include <unistd.h>
#include <limits>
#include <memory>
#include <queue>
#include <android-base/file.h>
@ -174,12 +175,18 @@ class BrotliCompressor final : public ICompressor {
class ZstdCompressor final : public ICompressor {
public:
ZstdCompressor(uint32_t compression_level) : ICompressor(compression_level){};
ZstdCompressor(uint32_t compression_level)
: ICompressor(compression_level), zstd_context_(ZSTD_createCCtx(), ZSTD_freeCCtx) {
ZSTD_CCtx_setParameter(zstd_context_.get(), ZSTD_c_compressionLevel, compression_level);
// FIXME: hardcoding a value of 12 here for 4k blocks, should change to be either set by
// user, or optimized depending on block size
ZSTD_CCtx_setParameter(zstd_context_.get(), ZSTD_c_windowLog, 12);
};
std::basic_string<uint8_t> Compress(const void* data, size_t length) const override {
std::basic_string<uint8_t> buffer(ZSTD_compressBound(length), '\0');
const auto compressed_size =
ZSTD_compress(buffer.data(), buffer.size(), data, length, GetCompressionLevel());
ZSTD_compress2(zstd_context_.get(), buffer.data(), buffer.size(), data, length);
if (compressed_size <= 0) {
LOG(ERROR) << "ZSTD compression failed " << compressed_size;
return {};
@ -193,6 +200,9 @@ class ZstdCompressor final : public ICompressor {
}
return buffer;
};
private:
std::unique_ptr<ZSTD_CCtx, decltype(&ZSTD_freeCCtx)> zstd_context_;
};
bool CompressWorker::CompressBlocks(const void* buffer, size_t num_blocks,