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
diff --git a/fs_mgr/libsnapshot/libsnapshot_cow/cow_compress.cpp b/fs_mgr/libsnapshot/libsnapshot_cow/cow_compress.cpp
index d023f19..466b93c 100644
--- a/fs_mgr/libsnapshot/libsnapshot_cow/cow_compress.cpp
+++ b/fs_mgr/libsnapshot/libsnapshot_cow/cow_compress.cpp
@@ -18,6 +18,7 @@
#include <unistd.h>
#include <limits>
+#include <memory>
#include <queue>
#include <android-base/file.h>
@@ -174,12 +175,18 @@
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 @@
}
return buffer;
};
+
+ private:
+ std::unique_ptr<ZSTD_CCtx, decltype(&ZSTD_freeCCtx)> zstd_context_;
};
bool CompressWorker::CompressBlocks(const void* buffer, size_t num_blocks,