ZSTD多线程压缩
测试代码:
1 // main.cpp 2 // 3 4 #include <iostream> 5 #include <fstream> 6 #include <vector> 7 #include <chrono> 8 #include <thread> 9 #include "./zstd/lib/zstd.h" 10 11 using byte = uint8_t; 12 using buffer = std::vector<byte>; 13 14 using std::chrono::milliseconds; 15 using std::chrono::steady_clock; 16 using std::chrono::duration_cast; 17 18 buffer read_file(const char* path) 19 { 20 std::ifstream s(path, std::ios::binary); 21 if (!s) 22 return {}; 23 s.seekg(0, std::ios::end); 24 auto length = s.tellg(); 25 s.seekg(0, std::ios::beg); 26 if (!length) 27 return {}; 28 buffer buf(length, 0); 29 auto ptr = (char*)buf.data(); 30 s.read(ptr, length); 31 if (!s) 32 return {}; 33 return buf; 34 } 35 36 int main() 37 { 38 // 1. 读取测试数据到内存 39 auto input = read_file("test.bmp"); 40 // 2. 预估输出缓冲区大小 41 auto bufSize = ZSTD_compressBound(input.size()); 42 // 3. 创建输出缓冲区 43 buffer output(bufSize, 0); 44 // 4. 设置压缩参数 45 auto level = 19; // ZSTD 多线程压缩时将 level 设置为 19 效率较高 46 auto num_threads = std::thread::hardware_concurrency(); // 获取CPU线程数 47 // 5. 创建压缩上下文 48 auto ctx = ZSTD_createCCtx(); 49 ZSTD_CCtx_setParameter(ctx, ZSTD_c_compressionLevel, level); 50 ZSTD_CCtx_setParameter(ctx, ZSTD_c_nbWorkers, num_threads); 51 // 6. 执行压缩 52 auto tp1 = steady_clock::now(); 53 auto result = ZSTD_compress2(ctx, output.data(), output.size(), input.data(), input.size()); 54 auto tp2 = steady_clock::now(); 55 // 7. 销毁压缩上下文 56 ZSTD_freeCCtx(ctx); 57 ctx = nullptr; 58 59 if (ZSTD_isError(result)) 60 { 61 std::cout << "error" << std::endl; 62 return 1; 63 } 64 65 auto time = duration_cast<milliseconds>(tp2 - tp1).count(); 66 67 std::cout << "original: " << input.size() << std::endl; 68 std::cout << "compressed: " << result << std::endl; 69 std::cout << "elapsed: " << time << "ms" << std::endl; 70 std::cout << "level: " << level << std::endl; 71 std::cout << "threads: " << num_threads << std::endl; 72 73 return 0; 74 }
测试代码使用VS2022编译通过。
编译ZSTD时确保预处理器有 ZSTD_MULTITHREAD=1 定义,可以直接引用源码文件夹里的 libzstd 项目。
结论:启用多线程压缩时, level <= 19 基本可以吃满CPU, level == 20 效率打五折, level >= 21 跟单线程没什么区别。