尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Bitcoin Core bench_bitcoin 基准测试框架实战:构建、运行与性能回归监控

Bitcoin Core bench_bitcoin 基准测试框架实战:构建、运行与性能回归监控 Bitcoin Core bench_bitcoin 基准测试框架实战构建、运行与性能回归监控【免费下载链接】bitcoinBitcoin Core integration/staging tree项目地址: https://gitcode.com/GitHub_Trending/bi/bitcoin本文基于 doc/benchmarking.md 展开讲解 Bitcoin Core 内置微基准测试框架bench_bitcoin的构建、运行与参数用法并结合 src/bench/ 目录下的框架源码与基准实现说明基准的注册与执行机制、结果输出格式以及如何用它监控 IBD、块模板生成等性能关键路径的回归。读完后可独立编译运行全部基准、按正则过滤单个基准、导出 CSV/JSON 结果并理解哪些代码路径值得新增基准。框架概览与基准覆盖范围doc/benchmarking.md 指出Bitcoin Core 内置一套基准测试框架覆盖密码学算法如 SHA1、SHA256、SHA512、RIPEMD160、Poly1305、ChaCha20、滚动布隆过滤器、硬币选择coin selection、线程队列thread queue、钱包余额wallet balance等组件。从构建清单 src/bench/CMakeLists.txt 可以看到当前实际编译进bench_bitcoin的基准源码规模远超文档列举的核心几类大致分为密码与编码crypto_hash.cppSHA1/SHA256/SHA512/SHA3/RIPEMD160/SipHash/MuHash 及各 SIMD 变体、chacha20.cpp、poly1305.cpp、ellswift.cpp、base58.cpp、bech32.cpp、strencodings.cpp、parse_hex.cppP2P 与网络组件addrman.cpp、blockencodings.cpp、bip324_ecdh.cpp、gcs_filter.cpp、txorphanage.cpp、peer_eviction.cpp、obfuscation.cpp、load_external.cpp外部加载地址库、asmap.cpp仅当WITH_EMBEDDED_ASMAP开启时编译见 src/bench/CMakeLists.txt#L74-L76共识与验证checkblock.cpp、checkblockindex.cpp、connectblock.cpp、verify_script.cpp、merkle_root.cpp、block_assemble.cpp块模板组装、duplicate_inputs.cpp、disconnected_transactions.cpp、readwriteblock.cpp内存池与事务图mempool_stress.cpp、mempool_eviction.cpp、mempool_ephemeral_spends.cpp、txgraph.cpp、rpc_mempool.cpp、rpc_blockchain.cpp、index_blockfilter.cpp容器与通用组件checkqueue.cpp线程队列、pool.cpp、prevector.cpp、rollingbloom.cpp、uint256_blob.cpp、hashpadding.cpp、random.cpp、streams_findbyte.cpp、util_time.cpp、logging.cpp、ccoins_caching.cpp、lockedpool.cpp、descriptors.cpp、cluster_linearize.cpp、sign_transaction.cpp、examples.cpp钱包仅当ENABLE_WALLET开启时加入编译见 src/bench/CMakeLists.txt#L78-L91coin_selection.cpp、wallet_balance.cpp、wallet_create.cpp、wallet_create_tx.cpp、wallet_encrypt.cpp、wallet_ismine.cpp、wallet_loading.cpp、wallet_migration.cpp。此外src/bench/CMakeLists.txt#L62-L65 通过target_raw_data_sources将真实区块数据 src/bench/data/block413567.raw 以benchmark::data命名空间暴露给基准函数使用保证验证类基准如CheckBlock跑在真实链上区块而非构造数据上。bench_bitcoin链接core_interface、test_util、bitcoin_node与Boost::headers库见 src/bench/CMakeLists.txt#L67-L72因此部分基准可以直接复用单元测试框架的数据目录机制。编译 bench_bitcoin按 doc/benchmarking.md 的说明跑基准只需编译bench_bitcoin这一个目标而不必构建完整的 bitcoind/比特币客户端cmake -B build -DBUILD_BENCHON cmake --build build -t bench_bitcoin对应源码事实根 CMakeLists.txt#L130 定义了option(BUILD_BENCH Build bench_bitcoin executable. OFF)默认关闭只有该选项开启时src/CMakeLists.txt#L434-L436 才会add_subdirectory(bench)把基准子树纳入构建。文档中特别提醒bench runner 在配置了-DCMAKE_BUILD_TYPEDebug时会发出警告即使不加 Debug也应考虑未开启日志打印器与锁分析对目标基准结果的影响——即构建选项改变了指令路径跨构建类型比较数字时需谨慎。运行与解读输出编译完成后直接在仓库根目录执行build/bin/bench_bitcoin输出形如 doc/benchmarking.md 给出的示例不同基准单位列名不同| ns/op | op/s | err% | total | benchmark |--------------------:|--------------------:|--------:|----------:|:---------- | 57,927,463.00 | 17.26 | 3.6% | 0.66 | AddrManAdd | 677,816.00 | 1,475.33 | 4.9% | 0.01 | AddrManGetAddr ... | ns/byte | byte/s | err% | total | benchmark |--------------------:|--------------------:|--------:|----------:|:---------- | 127.32 | 7,854,302.69 | 0.3% | 0.00 | Base58CheckEncode | 31.95 | 31,303,226.99 | 0.2% | 0.00 | Base58Decode各列含义ns/op每次操作平均耗时纳秒op/s每秒可完成的操作数ns/byte与byte/s对吞吐型基准基准函数里用bench.batch(n).unit(byte)声明了批量与单位例如 src/bench/crypto_hash.cpp#L25-L32 中 RIPEMD160 一次处理 1MB 缓冲单位换算成每字节err%本次运行结果的标准误差百分比数值越低说明测量越稳定total该基准的总耗时秒。想要更多选项用帮助命令build/bin/bench_bitcoin -h命令行选项详解全部选项在 src/bench/bench_bitcoin.cpp#L24-L36 的SetupBenchArgs中注册默认值与语义如下选项默认值作用-filterregex.*用正则表达式按名称选择要运行的基准-list关闭只列出匹配到的基准名不执行-min-timemilliseconds10单个基准的最短运行时间毫秒结果仍不稳定时可加大如-min-time5000-asymptoten1,n2,n3,...无对多个输入规模反复测量拟合算法的渐近时间复杂度输出 Big-O 估计-output-csvoutput.csv无导出最重要的基准结果evals、iterations、total、min/max/median为 CSV-output-jsonoutput.json无导出完整结果为 JSON-sanity-check关闭每个基准只跑 1 epoch × 1 次迭代且不打印结果用于快速验证基准能跑通-testdatadirpath无单元测试框架参数供使用BasicTestingSetup的基准指定数据目录几个典型用法# 列出所有基准名 build/bin/bench_bitcoin -list # 只跑名字含 SHA256 的基准 build/bin/bench_bitcoin -filterSHA256 # 跑通性自检CI 中常见用于确认基准可执行、不崩溃 build/bin/bench_bitcoin -sanity-check # 提高测量稳定性并导出结果供对比 build/bin/bench_bitcoin -min-time5000 -output-csvresult.csv对应实现位于 src/bench/bench.cpp#L75-L136 的BenchRunner::RunAll-filter用std::regex_match做全名匹配第 95 行-sanity-check会设置bench.epochs(1).epochIterations(1)并屏蔽输出第 105–108 行-min-time换算为纳秒后调用bench.minEpochTime第 111–115 行-asymptote则对每个规模调用bench.complexityN(n)并打印complexityBigO()第 117–125 行CSV/JSON 导出走 nanobench 的模板渲染第 132–135 行。另外帮助文本src/bench/bench_bitcoin.cpp#L74-L122还给出两个环境变量NANOBENCH_ENDLESS基准名让指定基准进入无限循环模式便于挂接外部 profiler例如NANOBENCH_ENDLESSMuHash ./bench_bitcoin -filterMuHashNANOBENCH_SUPPRESS_WARNINGS1在个别场景下抑制框架的稳定性警告。编写一个新基准框架的使用约定写在 src/bench/bench.h#L19-L36 的注释里配合BENCHMARK宏src/bench/bench.h#L69-L70完成定义即注册。以一个最简单的官方示例 src/bench/examples.cpp 为例#include bench/bench.h static void Trig(benchmark::Bench bench) { double d 0.01; bench.run([] { sum sum sin(d); d 0.000001; }); } BENCHMARK(Trig);模式是写一个static void Xxx(benchmark::Bench bench)函数函数内先做一次性准备再在bench.run([]{ ... })中放入被测代码最后用BENCHMARK(Xxx)注册。宏展开后会在静态存储区构造一个benchmark::BenchRunner对象将名字与函数压入全局BenchmarkMap见 src/bench/bench.h#L55-L65 与 src/bench/bench.cpp#L70-L73 的构造函数断言同名基准不可重复注册。吞吐型基准的写法见 src/bench/crypto_hash.cpp#L25-L32static void BenchRIPEMD160(benchmark::Bench bench) { uint8_t hash[CRIPEMD160::OUTPUT_SIZE]; std::vectoruint8_t in(BUFFER_SIZE,0); // BUFFER_SIZE 1MB bench.batch(in.size()).unit(byte).run([] { CRIPEMD160().Write(in.data(), in.size()).Finalize(hash); }); }batch(n)声明单次迭代处理了 n 个单元unit(byte)把结果显示为ns/byte与byte/s——这正是前面示例输出中 Base58/RIPEMD160 等基准按字节计时的来源。值得注意的两个工程细节防止被优化掉src/bench/crypto_hash.cpp#L193-L204 中 SipHash 基准使用ankerl::nanobench::doNotOptimizeAway(...)保留哈希结果examples.cpp 则用volatile全局变量承接累加和确保每次run()的工作量与前置条件完全一致帮助文本明确建议每次 run() 应做完全相同的工作。SIMD 实现横向对比src/bench/crypto_hash.cpp#L43-L85 对 SHA256 分别注册了 STANDARD / SSE4 / AVX2 / SHANI 四种实现每次基准内部先强制切换到目标实现SHA256AutoDetect(sha256_implementation::USE_SSE4)等测完恢复自动检测。这种同一条基准管线、切换底层实现的写法是评估汇编/指令集加速收益的标准范式。滚动布隆过滤器src/bench/rollingbloom.cpp 构造CRollingBloomFilter(120000, 0.000001)即内存池中跟踪约 12 万个交易的参数分别测量插入查询RollingBloom与整表重置RollingBloomReset两条路径。新基准文件加入 src/bench/CMakeLists.txt 的add_executable(bench_bitcoin ...)列表后即可被-list发现、按名字过滤运行。框架执行机制从注册到输出从源码结构看整个框架是静态注册 统一执行器两段式设计注册每个基准文件底部的BENCHMARK(...)在程序启动前静态初始化阶段把name - function存入BenchRunner::benchmarks()这个全局std::mapsrc/bench/bench.cpp#L64-L73因此遍历即按名称字典序执行-list输出的顺序也是排序后的。执行src/bench/bench_bitcoin.cpp#L63-L142 的main解析参数后组装benchmark::Args调用BenchRunner::RunAll(args)。执行器逐条做正则过滤、可选 sanity-check 模式、设置minEpochTime或复杂度规模然后把控制权交给 nanobench内置于 src/bench/nanobench.h完成 epoch 采样、中位数/误差统计与表格打印。结果落盘-output-csv使用固定模板输出Benchmark, evals, iterations, total, min, max, median七列src/bench/bench.cpp#L132-L134-output-json使用 nanobench 的完整 JSON 模板。两者适合接入 CI 或回归对比脚本。与测试框架的桥接使用BasicTestingSetup或其子类的基准可以拿到命令行参数src/bench/bench.cpp#L27-L41 通过g_bench_command_line_args/G_TEST_GET_FULL_NAME两个钩子让每个基准的 datadir 落在以基准名命名的目录下-testdatadir由parseTestSetupArgssrc/bench/bench_bitcoin.cpp#L51-L61透传给内部测试环境。基准的价值边界什么时候该加、什么时候不该用doc/benchmarking.md 的 Notes 一节给出了项目对基准的定位值得原样遵循用途基准用于监控性能回归并作为未来性能改进的度量范围scope。应覆盖影响系统性能关键功能的组件——函数是性能关键的当且仅当其性能会直接影响用户、且性能劣化的代价很高。文档列举的非穷尽清单初始块下载IBD代价是 IBD 变慢会降低全节点运行的可及性块模板创建变慢可能导致矿工收益手续费收入下降块传播变慢会提高孤儿块率、加剧挖矿中心化趋势。合入标准以性能改进为目的的改动若无法证明明确的端到端性能提升可能被拒绝即使有提升若代码膨胀或评审/维护成本过高到不足以证明收益同样可能被拒。这意味着提交基准改进时应同时给出基准数据与代码复杂度的论证。边界基准不适合测试拒绝服务DoS问题——它们被限制在固定输入集上存在偏置探索输入空间应使用 doc/fuzzing.md 所述的模糊测试。获得稳定结果的实操建议bench_bitcoin -h的帮助文本src/bench/bench_bitcoin.cpp#L74-L122内置了官方给出的稳定性提示结合源码可归纳为固定 CPU 状态用 pyperf 等工具关闭频率调节与 Turbo Boost追求最佳结果时做 CPU 绑核与隔离每次迭代做相同工作例如向std::vector插入在容量耗尽时会触发重分配这类非均匀前置条件会污染测量加大运行时间结果仍不稳定时用-min-time5000让每个基准至少跑 5 秒对应RunAll中minEpochTime的换算逻辑src/bench/bench.cpp#L111-L115关注err%列输出表格中的误差百分比直接来自 nanobench 的多次 epoch 采样跨机器对比时误差过大的数字不可比更深的宏观监控对于 reindex、IBD 这类整链级别的性能度量仓库文档建议配合外部的 benchcoin 项目使用它基于同一份代码库做全节点吞吐测试本文不再展开。小结bench_bitcoin由一行cmake -B build -DBUILD_BENCHON开启构建用-list/-filter/-min-time/-sanity-check/-output-csv/-output-json覆盖发现、筛选、测稳、自检、导出的完整工作流其静态注册 统一执行器的实现src/bench/bench.h、src/bench/bench.cpp让新增基准只需一个函数加一行BENCHMARK(...)注册。将其作为性能回归的守门手段时应牢记文档划定的边界基准守住 IBD、块模板、块传播这类高代价路径的性能底线而输入空间的健壮性探索交给模糊测试。【免费下载链接】bitcoinBitcoin Core integration/staging tree项目地址: https://gitcode.com/GitHub_Trending/bi/bitcoin创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表