计算预算

摘要

每条指令默认分配 20 万 CU,每笔交易最多 140 万 CU。可使用 SetComputeUnitLimitSetComputeUnitPrice 指令进行优化。 优先费用基于请求的 CU 数量,而非实际使用量。

计算单元限制

每条指令分配 默认 200,000 CU,每笔交易上限为 1,400,000 CU。如果没有显式的 SetComputeUnitLimit 指令, 默认值将根据指令类型计算

Default CU limit calculation
default_cu_limit = (num_non_migratable_builtin_instructions * 3,000)
+ (num_not_migrated_builtin_instructions * 3,000)
+ (num_non_builtin_instructions * 200,000)
+ (num_migrated_builtin_instructions * 200,000)

结果会被限制在 MAX_COMPUTE_UNIT_LIMIT(1,400,000)以内。

你可以在交易中包含 SetComputeUnitLimit 指令来覆盖默认值。

确定合适的 CU 限制方法:

  1. 通过模拟交易测量 CU 消耗。
  2. 在模拟值基础上增加 10% 的安全余量。

优先费用由交易中请求的计算单元上限决定,而不是实际使用的计算单元数量。如果你设置的计算单元上限过高或直接使用默认值,将会为未使用的计算单元支付费用。

计算预算指令

Compute Budget ProgramComputeBudget111111111111111111111111111111)包含四种指令。

变体判别符参数类型描述
RequestHeapFrame1bytesu32每个交易中程序请求的堆大小(字节)
SetComputeUnitLimit2unitsu32交易可消耗的最大 CU 数
SetComputeUnitPrice3micro_lamportsu64CU 单价(微 lamports)
SetLoadedAccountsDataSizeLimit4bytesu32交易可加载的账户数据总字节数上限

来源:ComputeBudgetInstruction 枚举

约束与错误条件

处理计算预算指令时,适用以下规则:

  • 每种类型仅允许一个:每笔交易中,每种指令变体只能包含一个。若包含重复项,将导致 DuplicateInstruction 错误(整个交易失败)。
  • RequestHeapFrame:该值必须介于 MIN_HEAP_FRAME_BYTES(32 KiB)和 MAX_HEAP_FRAME_BYTES(256 KiB)之间,并且必须为1,024 的倍数。否则,交易将以 InvalidInstructionData 失败。堆大小适用于交易中调用的每个程序(包括 CPI)。
  • SetComputeUnitLimit:接受任意 u32 值。实际限制会被限制为 MAX_COMPUTE_UNIT_LIMIT(1,400,000)。
  • SetComputeUnitPrice:接受任意 u64 值(0 到 u64::MAX)。
  • SetLoadedAccountsDataSizeLimit:该值必须大于 0(NonZeroU32)。若为 0,将导致 InvalidLoadedAccountsDataSizeLimit。实际限制会被限制为 MAX_LOADED_ACCOUNTS_DATA_SIZE_BYTES(64 MiB)。
  • 未识别的数据:任何发送到 Compute Budget Program 且无法反序列化为已知变体的指令,都会以 InvalidInstructionData 失败。

下文的调度器成本模型描述了 validator 内部的预执行成本估算。大多数开发者只需关注上文提到的 compute budget 指令。

调度器成本模型

validator 的 scheduler 使用 cost model执行前估算交易的资源使用情况。这些预执行成本估算用于判断交易是否能适配区块剩余容量。它们与执行期间发生的 CU 计量是分开的。

调度器总成本由五个部分组成 (UsageCostDetails::sum):

Scheduler cost formula
total_cost = signature_cost
+ write_lock_cost
+ data_bytes_cost
+ programs_execution_cost
+ loaded_accounts_data_size_cost

成本组成部分

组成部分描述
Signature cost每种签名类型的单次签名成本
Write lock cost每个可写账户
Instruction data cost基于指令数据字节总数
Programs execution cost来自 compute budget 或默认值的 CU 限额
Loaded accounts data cost基于已加载账户数据总大小

所有数值均以 compute unit(CU)为单位。

调度器成本常量

投票交易成本

投票交易无论实际内容如何,均使用 固定成本 3,428 CU

区块限制

调度器会强制执行每个区块的限制。如果添加某笔交易会超出任何限制,则该交易不会被包含进区块。

SIMD-0286 提议将 MAX_BLOCK_UNITS 增加到 100,000,000。

执行预算常量

以下常量来自 execution_budget.rs 定义了交易执行期间的运行时限制:

常量数值说明
MAX_COMPUTE_UNIT_LIMIT1,400,000每笔交易的最大 CU 限制
DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT200,000每条非内置指令的默认 CU
MAX_BUILTIN_ALLOCATION_COMPUTE_UNIT_LIMIT3,000每条内置指令的默认 CU(SIMD-0170)
DEFAULT_HEAP_COST8 CU每 32 KiB 堆页面的成本
DEFAULT_INVOCATION_COST1,000 CU一次 CPI 调用的成本
INVOKE_UNITS_COST_SIMD_0339946 CU启用 SIMD-0339 后的 CPI 调用成本
MIN_HEAP_FRAME_BYTES32,768最小堆大小(32 KiB)
MAX_HEAP_FRAME_BYTES262,144最大堆大小(256 KiB)
MAX_LOADED_ACCOUNTS_DATA_SIZE_BYTES67,108,864每笔交易最大加载账户数据(64 MiB)
MAX_INSTRUCTION_STACK_DEPTH5最大指令堆栈深度(顶层 + CPI)
MAX_INSTRUCTION_STACK_DEPTH_SIMD_02689启用 SIMD-0268 后的最大指令堆栈深度(顶层 + CPI)
MAX_CALL_DEPTH64单个程序内最大 SBF-to-SBF 调用深度
STACK_FRAME_SIZE4,096 字节单个 SBF 堆栈帧的大小

Is this page helpful?

Table of Contents

Edit Page

管理者

©️ 2026 Solana 基金会版权所有
取得联系