比特币核心脚本校验分几条线程:-par 的默认值与边界 图 1
比特币核心脚本校验分几条线程:-par 的默认值与边界 · 图 1

比特币全节点最重的日常工作是验签名:每笔交易的每个输入都要做椭圆曲线运算,块越大验得越多。Bitcoin Core 为此设计了专门的脚本校验线程池,把签名验证从主线程剥离出来并行跑。控制这个池子的参数就是一个字的 -par,本文按 Bitcoin Core v31.0 源码核对它的换算规则与适用边界。

一、三种写法对应三种策略

源码帮助文本把这个参数定义为”设置脚本验证线程数”,规则分三档。写 0(默认)表示自动:由程序按可用的 CPU 核心数决定线程数。写正数表示显式指定,想开几条就填几条,上限是源码常量 MAX_SCRIPTCHECK_THREADS 定义的十五条,超出会被抬回上限。写负数是最有特色的一档:含义是”留出这么多核心别用”,比如 -par=-2 表示把机器上除两颗核之外的核心都拿去验签名——服务器上还跑着钱包服务、索引器或桌面环境时,这一档让你在吞吐与共存之间划线,不用自己算核心数。

二、默认自动档的换算逻辑

自动档的线程数由调度器按核心数推导,规则里有一条常识性修正:如果只有一颗可用核心,就不另开校验线程,签名验证直接在主线程做——开线程换来的是上下文切换开销而不是并行收益。源码里线程数封顶十五,也说明设计预期:区块验证的瓶颈不只是核心数,还会撞上锁、内存带宽与单线程分发能力,堆更多校验线程收益递减。这也是”默认自动、极少需要手调”的原因:绝大多数部署让程序自己决定就好。

三、调它之前先想清楚瓶颈在哪

真正会去改 -par 的场景不多,且各有明确的动机。嵌入式板卡或小内存云主机上,自动档可能开出偏多的线程,把内存和调度压力都抬高,这时用负数留核或显式小值更稳。反方向的场景是磁盘和网络都跟得上、CPU 成为瓶颈的高配节点,可以确认自动档是否已按满核心数工作。需要泼冷水的场景是同步慢但 CPU 空闲的节点——瓶颈多半在块下载调度、磁盘顺序读或中继延迟,校验线程加多少都不动这块。判断方法是观察同步期的 CPU 占用形态:校验线程池吃满与闲着,对应完全不同的处方。

四、与相邻参数的分工

脚本验证缓存的大小由 maxsigcachesize 控制,那是内存预算不是并行度;dbcache 管链上数据缓存,同样是另一件事。-par 只管”验签这件事用几条线程”,改它不改变任何共识规则——验证结果与单线程完全一致,变的只是机器消化区块的速度。作为收尾提醒:任何并发参数都值得在升级版本后重新核对一次换算逻辑,v31.0 的默认值与边界如上所述,新版本行为可能调整,以对应版本源码为准。

五、配置落点与可观测性

这个参数可以写在 bitcoin.conf 里,也可以命令行传入;桌面版和图形界面通常不暴露它,走配置文件的居多。验证当前生效值有个简单办法:启动参数摘要会写进调试日志,形如使用若干条脚本校验线程的那几行会直接报告实际线程数——比对照配置文件推断可靠,因为它反映的是经过换算后的真实结果,负数留核的换算对不对,日志里一眼可判。升级大版本后值得重看一次这几行:换算逻辑、上限与默认策略都属于实现细节,历史上曾经调整过,参数写法没变但结果可能不同。收尾再强调一次边界:par 是并发度旋钮,和区块验证的正确性无关,任何调线程数让节点跑得更安全的说法都不成立,它唯一的作用是在算力预算与同步速度之间选一个平衡点。

本文所有行为按 Bitcoin Core v31.0 源码核对,不构成任何投资建议。

比特币核心脚本校验分几条线程:-par 的默认值与边界 图 2
比特币核心脚本校验分几条线程:-par 的默认值与边界 · 图 2