TwoBufQueue
489.55
ReaderWriterQueue
801.00
rigtorp/SPSCQueue
326.11
atomic_queue
186.30
比较生产者线程把消息发送到队列的速度和耗时:吞吐越高越好,生产者发送耗时的 p50 / p99 / p999 越低越好。与 ReaderWriterQueue、rigtorp/SPSCQueue、atomic_queue 对比。
测生产者向队列发送消息的吞吐与耗时:消息交给队列有多快,生产者每条消息要花多少时间。
对比 TwoBufQueue、ReaderWriterQueue、rigtorp/SPSCQueue 和 atomic_queue,消息长度为 8 / 16 / 32 / 64 B。TwoBufQueue 使用普通 write,每写入一条消息就发布进度,并开启当前块扫描。业务回调循环次数为 0,消费者仍正常接收消息并调用回调。
测试流程:提前准备消息 → 生产者连续发送并计时 → 停止计时 → 等待本轮消息消费完成。所有队列采用相同的消息条数和长度。
计时范围:计入生产者发送阶段的消息复制、进度发布、发送中发生的申请块或换块,以及可能的重试等待。输入准备、轮末交接与回调排空在计时外执行;复制和消费线程同时运行,仍会影响生产者的实际速度。
吞吐:成功发送的消息总数 ÷ 生产者累计发送时间,单位 M条/s(每秒百万条消息),越高越好。数据吞吐 GB/s 按消息净负载字节数计算。
p50、p99、p999 都是生产者线程发送消息耗时的分位数,越低越好。为精确测量很短的发送操作,每连续发送 1,000 条成功消息计时一次,再将这组时间除以 1,000,得到一个“平均每条发送耗时”样本。
p50(50% 分位):在一次运行中,50% 的分组样本,其平均每条发送耗时不超过这个值。
p99(99% 分位):在一次运行中,99% 的分组样本,其平均每条发送耗时不超过这个值。
p999(99.9% 分位):在一次运行中,99.9% 的分组样本,其平均每条发送耗时不超过这个值。
每次运行分别计算这些分位数,表中再取三次运行结果的平均值。这里衡量的是生产者提交消息的开销:分位数来自每组 1,000 条的平均耗时,不是单次 write 调用的分位数,也不是从发送到消费者收到消息的端到端延时。
同一长度的四个队列放在一起;吞吐单位 M条/s。
TwoBufQueue 两层数据池各固定 256 MiB,合计 512 MiB;原生 SPSC 的消息存储预算为 256 MiB。备用槽、padding 计入预算,控制结构另计。
每个队列的吞吐、p50、p99、p999 使用同一套参数,8 / 16 / 32 / 64 B 也共用这套调优参数。按权重 35% / 30% / 20% / 15% 综合选参,四种长度等权参与。原生容量随消息长度按固定字节预算推导,复制策略沿用各长度已固定的负载实现。
此次用共同参数对应的遍历阶段三次实测值更新表格,因此数值与旧版逐项独立选优不同;原始记录保留,ReaderWriterQueue 的邻域补测另外保存。
同消息长度使用相同背景色;TwoBufQueue 整行加粗并描边。吞吐下方显示三次测量的最小值与最大值。
| 实现 / 复制方式 | 吞吐 M条/s | 数据吞吐 GB/s | 生产者发送耗时 p50 ns/条 | 生产者发送耗时 p99 ns/条 | 生产者发送耗时 p999 ns/条 | 背压% |
|---|---|---|---|---|---|---|
| 8 B | ||||||
| TwoBufQueue普通 write · 首字节读回 | 489.548488.993 – 489.940 | 3.916 | 2.000 | 3.042 | 7.236 | 0%0 / 30,000,000 |
| ReaderWriterQueue完整成员复制 | 801.002649.604 – 893.901 | 6.408 | 1.222 | 1.972 | 2.694 | 0%0 / 30,000,000 |
| rigtorp/SPSCQueue成员复制+目标写预取 | 326.105313.386 – 333.183 | 2.609 | 3.000 | 4.347 | 6.708 | 0%0 / 30,000,000 |
| atomic_queue完整成员复制 | 186.298175.399 – 198.343 | 1.490 | 4.986 | 17.583 | 36.542 | 0%0 / 30,000,000 |
| 16 B | ||||||
| TwoBufQueue普通 write · 首字节读回 | 449.506446.715 – 451.387 | 7.192 | 2.167 | 3.167 | 4.556 | 0%0 / 30,000,000 |
| ReaderWriterQueue先清零,再完整 memcpy | 767.375724.706 – 800.675 | 12.278 | 1.319 | 2.569 | 5.653 | 0%0 / 30,000,000 |
| rigtorp/SPSCQueue成员复制+目标写预取 | 267.481230.185 – 304.328 | 4.280 | 3.097 | 5.861 | 8.861 | 0%0 / 30,000,000 |
| atomic_queue完整成员复制 | 48.65543.680 – 52.157 | 0.778 | 13.375 | 40.083 | 43.278 | 0%0 / 30,000,000 |
| 32 B | ||||||
| TwoBufQueue普通 write · 首字节读回 | 378.646354.070 – 393.536 | 12.117 | 2.458 | 3.972 | 9.000 | 0%0 / 30,000,000 |
| ReaderWriterQueue先清零,再完整 memcpy | 422.627390.659 – 440.068 | 13.524 | 2.667 | 4.903 | 9.722 | 0%0 / 30,000,000 |
| rigtorp/SPSCQueue成员复制+目标写预取 | 220.680172.547 – 252.079 | 7.062 | 4.056 | 14.097 | 17.292 | 0%0 / 30,000,000 |
| atomic_queue完整成员复制 | 30.20228.745 – 31.363 | 0.966 | 35.847 | 69.181 | 314.000 | 0%0 / 30,000,000 |
| 64 B | ||||||
| TwoBufQueue普通 write · 首字节读回 | 277.866250.553 – 296.094 | 17.783 | 3.208 | 9.486 | 19.889 | 0%0 / 30,000,000 |
| ReaderWriterQueue完整成员复制 | 204.257142.833 – 239.658 | 13.072 | 4.681 | 9.875 | 20.361 | 0%0 / 30,000,000 |
| rigtorp/SPSCQueue成员复制+目标写预取 | 99.41565.287 – 126.390 | 6.363 | 7.361 | 22.861 | 26.194 | 0%0 / 30,000,000 |
| atomic_queue完整成员复制 | 45.19339.567 – 48.690 | 2.892 | 29.764 | 40.028 | 56.222 | 0%0 / 30,000,000 |
表中的 p50 / p99 / p999 衡量生产者线程发送消息的耗时:先统计每组 1,000 次成功写入的平均耗时的分位数,再对三次运行取平均;并非单次调用或端到端延时。同一行所有指标来自同一配置;同一队列的四种长度也共用调优参数。综合选参是一套参数下的取舍,各单项不再声称分别最优。点击任一指标均跳到该行同一套完整参数。背压% = 背压消息条数 ÷ 总消息条数 × 100%,使用三次吞吐测量的合计数;下方同时列出分子 / 分母。每条消息即使写入失败多次,也只算一条背压消息。
每项均保留三次实测,不删除慢结果;四项指标使用同一个参数编号。
| 实现 / 指标 | 第 1 次 | 第 2 次 | 第 3 次 | 平均 |
|---|---|---|---|---|
| TwoBufQueue吞吐 M条/s · 参数 66ccd405370d | 488.993 | 489.712 | 489.940 | 489.548 |
| TwoBufQueuep50 ns/条 · 参数 66ccd405370d | 2.000 | 2.000 | 2.000 | 2.000 |
| TwoBufQueuep99 ns/条 · 参数 66ccd405370d | 3.667 | 2.667 | 2.792 | 3.042 |
| TwoBufQueuep999 ns/条 · 参数 66ccd405370d | 7.250 | 6.292 | 8.167 | 7.236 |
| ReaderWriterQueue吞吐 M条/s · 参数 05c6a693ebc0 | 859.500 | 649.604 | 893.901 | 801.002 |
| ReaderWriterQueuep50 ns/条 · 参数 05c6a693ebc0 | 1.208 | 1.208 | 1.250 | 1.222 |
| ReaderWriterQueuep99 ns/条 · 参数 05c6a693ebc0 | 2.042 | 1.833 | 2.042 | 1.972 |
| ReaderWriterQueuep999 ns/条 · 参数 05c6a693ebc0 | 3.417 | 2.125 | 2.542 | 2.694 |
| rigtorp/SPSCQueue吞吐 M条/s · 参数 ddbed3127220 | 331.746 | 333.183 | 313.386 | 326.105 |
| rigtorp/SPSCQueuep50 ns/条 · 参数 ddbed3127220 | 3.125 | 2.917 | 2.958 | 3.000 |
| rigtorp/SPSCQueuep99 ns/条 · 参数 ddbed3127220 | 4.583 | 4.208 | 4.250 | 4.347 |
| rigtorp/SPSCQueuep999 ns/条 · 参数 ddbed3127220 | 7.042 | 6.583 | 6.500 | 6.708 |
| atomic_queue吞吐 M条/s · 参数 f54226336788 | 198.343 | 175.399 | 185.152 | 186.298 |
| atomic_queuep50 ns/条 · 参数 f54226336788 | 4.917 | 5.000 | 5.042 | 4.986 |
| atomic_queuep99 ns/条 · 参数 f54226336788 | 7.167 | 8.875 | 36.708 | 17.583 |
| atomic_queuep999 ns/条 · 参数 f54226336788 | 37.500 | 34.708 | 37.417 | 36.542 |
| 实现 / 指标 | 第 1 次 | 第 2 次 | 第 3 次 | 平均 |
|---|---|---|---|---|
| TwoBufQueue吞吐 M条/s · 参数 c15f5c466114 | 451.387 | 450.415 | 446.715 | 449.506 |
| TwoBufQueuep50 ns/条 · 参数 c15f5c466114 | 2.167 | 2.167 | 2.167 | 2.167 |
| TwoBufQueuep99 ns/条 · 参数 c15f5c466114 | 3.333 | 3.000 | 3.167 | 3.167 |
| TwoBufQueuep999 ns/条 · 参数 c15f5c466114 | 4.375 | 4.333 | 4.958 | 4.556 |
| ReaderWriterQueue吞吐 M条/s · 参数 1fe946d9a7bc | 724.706 | 800.675 | 776.744 | 767.375 |
| ReaderWriterQueuep50 ns/条 · 参数 1fe946d9a7bc | 1.208 | 1.500 | 1.250 | 1.319 |
| ReaderWriterQueuep99 ns/条 · 参数 1fe946d9a7bc | 2.375 | 2.958 | 2.375 | 2.569 |
| ReaderWriterQueuep999 ns/条 · 参数 1fe946d9a7bc | 3.375 | 9.542 | 4.042 | 5.653 |
| rigtorp/SPSCQueue吞吐 M条/s · 参数 488489a115af | 304.328 | 230.185 | 267.931 | 267.481 |
| rigtorp/SPSCQueuep50 ns/条 · 参数 488489a115af | 3.042 | 3.208 | 3.042 | 3.097 |
| rigtorp/SPSCQueuep99 ns/条 · 参数 488489a115af | 5.750 | 6.375 | 5.458 | 5.861 |
| rigtorp/SPSCQueuep999 ns/条 · 参数 488489a115af | 9.417 | 9.583 | 7.583 | 8.861 |
| atomic_queue吞吐 M条/s · 参数 7afaa762ae1a | 50.128 | 52.157 | 43.680 | 48.655 |
| atomic_queuep50 ns/条 · 参数 7afaa762ae1a | 6.625 | 12.625 | 20.875 | 13.375 |
| atomic_queuep99 ns/条 · 参数 7afaa762ae1a | 38.375 | 40.875 | 41.000 | 40.083 |
| atomic_queuep999 ns/条 · 参数 7afaa762ae1a | 42.292 | 43.667 | 43.875 | 43.278 |
| 实现 / 指标 | 第 1 次 | 第 2 次 | 第 3 次 | 平均 |
|---|---|---|---|---|
| TwoBufQueue吞吐 M条/s · 参数 9ae1ffe54571 | 354.070 | 388.333 | 393.536 | 378.646 |
| TwoBufQueuep50 ns/条 · 参数 9ae1ffe54571 | 2.458 | 2.458 | 2.458 | 2.458 |
| TwoBufQueuep99 ns/条 · 参数 9ae1ffe54571 | 4.083 | 3.875 | 3.958 | 3.972 |
| TwoBufQueuep999 ns/条 · 参数 9ae1ffe54571 | 12.542 | 6.042 | 8.417 | 9.000 |
| ReaderWriterQueue吞吐 M条/s · 参数 37b8e391eac3 | 437.154 | 440.068 | 390.659 | 422.627 |
| ReaderWriterQueuep50 ns/条 · 参数 37b8e391eac3 | 3.042 | 2.958 | 2.000 | 2.667 |
| ReaderWriterQueuep99 ns/条 · 参数 37b8e391eac3 | 6.167 | 4.208 | 4.333 | 4.903 |
| ReaderWriterQueuep999 ns/条 · 参数 37b8e391eac3 | 10.750 | 9.500 | 8.917 | 9.722 |
| rigtorp/SPSCQueue吞吐 M条/s · 参数 626a79b8b850 | 237.414 | 172.547 | 252.079 | 220.680 |
| rigtorp/SPSCQueuep50 ns/条 · 参数 626a79b8b850 | 4.042 | 4.042 | 4.083 | 4.056 |
| rigtorp/SPSCQueuep99 ns/条 · 参数 626a79b8b850 | 13.917 | 15.000 | 13.375 | 14.097 |
| rigtorp/SPSCQueuep999 ns/条 · 参数 626a79b8b850 | 15.833 | 18.875 | 17.167 | 17.292 |
| atomic_queue吞吐 M条/s · 参数 b998250847cc | 31.363 | 28.745 | 30.499 | 30.202 |
| atomic_queuep50 ns/条 · 参数 b998250847cc | 35.042 | 37.000 | 35.500 | 35.847 |
| atomic_queuep99 ns/条 · 参数 b998250847cc | 110.958 | 41.833 | 54.750 | 69.181 |
| atomic_queuep999 ns/条 · 参数 b998250847cc | 818.792 | 54.000 | 69.208 | 314.000 |
| 实现 / 指标 | 第 1 次 | 第 2 次 | 第 3 次 | 平均 |
|---|---|---|---|---|
| TwoBufQueue吞吐 M条/s · 参数 dde24d688026 | 250.553 | 286.951 | 296.094 | 277.866 |
| TwoBufQueuep50 ns/条 · 参数 dde24d688026 | 3.208 | 3.167 | 3.250 | 3.208 |
| TwoBufQueuep99 ns/条 · 参数 dde24d688026 | 6.750 | 7.458 | 14.250 | 9.486 |
| TwoBufQueuep999 ns/条 · 参数 dde24d688026 | 18.417 | 11.042 | 30.208 | 19.889 |
| ReaderWriterQueue吞吐 M条/s · 参数 8f16777e2f59 | 142.833 | 230.279 | 239.658 | 204.257 |
| ReaderWriterQueuep50 ns/条 · 参数 8f16777e2f59 | 4.875 | 5.083 | 4.083 | 4.681 |
| ReaderWriterQueuep99 ns/条 · 参数 8f16777e2f59 | 11.125 | 10.792 | 7.708 | 9.875 |
| ReaderWriterQueuep999 ns/条 · 参数 8f16777e2f59 | 30.708 | 15.333 | 15.042 | 20.361 |
| rigtorp/SPSCQueue吞吐 M条/s · 参数 0d1082002fb0 | 65.287 | 106.570 | 126.390 | 99.415 |
| rigtorp/SPSCQueuep50 ns/条 · 参数 0d1082002fb0 | 7.750 | 6.875 | 7.458 | 7.361 |
| rigtorp/SPSCQueuep99 ns/条 · 参数 0d1082002fb0 | 22.958 | 22.250 | 23.375 | 22.861 |
| rigtorp/SPSCQueuep999 ns/条 · 参数 0d1082002fb0 | 26.542 | 25.125 | 26.917 | 26.194 |
| atomic_queue吞吐 M条/s · 参数 b4753ca6ef75 | 39.567 | 48.690 | 47.322 | 45.193 |
| atomic_queuep50 ns/条 · 参数 b4753ca6ef75 | 34.292 | 25.375 | 29.625 | 29.764 |
| atomic_queuep99 ns/条 · 参数 b4753ca6ef75 | 41.417 | 38.792 | 39.875 | 40.028 |
| atomic_queuep999 ns/条 · 参数 b4753ca6ef75 | 78.833 | 44.708 | 45.125 | 56.222 |
吞吐与延时分别运行三次,运行模式和随机种子按实际记录列出。p999 每次来自约 10,000 个分组样本,尾部约 10 个,容易受调度波动影响。
按队列只列一次初始化参数,所有消息长度共用。容量条数等随长度变化的值用取值规则列出,完整运行参数保存在导出的 JSON 与原始记录中。
完整列出 61 项测试类参数及构造 / 模板参数。消息长度列为统一取值列表;容量条数和已固定的复制配置等随长度变化的值用 by_payload_bytes 对应关系表示,不重复四套参数。
| 参数 | 取值 |
|---|---|
| transport | two_buf_queue |
| mode | ["throughput", "write_latency"] |
| payload_bytes | [8, 16, 32, 64] |
| messages | 10000000 |
| warmup_messages | 50000 |
| callback_iterations | 0 |
| verify_payload | false |
| prepared_input | true |
| variable_payload | true |
| prepared_input_limit_bytes | 268435456 |
| measure_callback_time | true |
| producer_interval_ns | 0 |
| source_block_size | 1048576 |
| source_pool_min | 256 |
| source_pool_max | 256 |
| source_queue_capacity | 512 |
| writer_backpressure | drop |
| writer_spin_count | 1000 |
| writer_wait_timeout_ms | 5000 |
| output_block_size | 16777216 |
| output_frame_capacity | 1024 |
| output_pool_min | 16 |
| output_pool_max | 16 |
| output_queue_capacity | 512 |
| cancel_claim_mode | tail |
| output_mode | spsc |
| output_reader_mode | wait_signal |
| output_reader_count | 1 |
| output_retry_wait_us | 1000 |
| output_enable_stats | false |
| is_scan_current | true |
| reader_spin_count | 1000 |
| rescan_interval_ns | 1000000 |
| rescan_max_interval_ns | 1000000 |
| consumer_cpu | -1 |
| producer_cpu | -1 |
| producer_qos | user_interactive |
| round_storage_bytes | 214748364 |
| fixed_round_boundaries | true |
| spsc_buffer_bytes | 0 |
| prefault_producer_buffers | true |
| finish_timeout_ms | 5000 |
| work_wait_min_ms | 1 |
| finish_retry_ms | 1 |
| publish_count | 1 |
| use_write_session | false |
| rigtorp_write_prefetch | true |
| readerwriterqueue_copy_after_zero | false |
| spsc_capacity | 0 |
| retry_yield_every | 1024 |
| spsc_idle_spins | 1000 |
| spsc_idle_sleep_ns | 0 |
| timer | auto |
| sample_every | 32 |
| max_samples | 1000000 |
| latency_batch_size | 1000 |
| timer_calibration_samples | 16384 |
| call_batch_size | 256 |
| random_seed | [42, 43, 44] |
| timeout_seconds | 180 |
| buffer_budget_bytes | 536870912 |
| 参数 | 取值 |
|---|---|
| source_thread_id | 0 |
| read_layer1_thread_count | 1 |
| writer_queue_enable_stats | false |
| message_prefix_bytes | 0 |
| writer_count | 1 |
| source_copy_thread_count | 1 |
| callback_thread_count | 1 |
| pool_depth_instrumentation | false |
| callback_signature | (thread_id, data, payload_bytes) |
| callback_business_iterations | 0 |
| writer_type | OwnedWriter<Writer<1, false, uint16_t, void>> |
| writer_api | Writer::write |
| ordinary_write_readback | true |
| sync_context | void |
| callback_wrapper | FixedRecordCallback<PayloadBytes, Sink> |
| source_pool_payload_bytes | 268435456 |
| reader_pool_payload_bytes | 268435456 |
完整列出 61 项测试类参数及构造 / 模板参数。消息长度列为统一取值列表;容量条数和已固定的复制配置等随长度变化的值用 by_payload_bytes 对应关系表示,不重复四套参数。
| 参数 | 取值 |
|---|---|
| transport | readerwriterqueue |
| mode | ["throughput", "write_latency"] |
| payload_bytes | [8, 16, 32, 64] |
| messages | 10000000 |
| warmup_messages | 50000 |
| callback_iterations | 0 |
| verify_payload | false |
| prepared_input | true |
| variable_payload | true |
| prepared_input_limit_bytes | 268435456 |
| measure_callback_time | true |
| producer_interval_ns | 0 |
| source_block_size | 65536 |
| source_pool_min | 4096 |
| source_pool_max | 4096 |
| source_queue_capacity | 4096 |
| writer_backpressure | drop |
| writer_spin_count | 1000 |
| writer_wait_timeout_ms | 5000 |
| output_block_size | 1048576 |
| output_frame_capacity | 1024 |
| output_pool_min | 256 |
| output_pool_max | 256 |
| output_queue_capacity | 512 |
| cancel_claim_mode | tail |
| output_mode | spsc |
| output_reader_mode | wait_signal |
| output_reader_count | 1 |
| output_retry_wait_us | 1000 |
| output_enable_stats | false |
| is_scan_current | false |
| reader_spin_count | 1000 |
| rescan_interval_ns | 1000000 |
| rescan_max_interval_ns | 1000000 |
| consumer_cpu | -1 |
| producer_cpu | -1 |
| producer_qos | user_interactive |
| round_storage_bytes | 214748364 |
| fixed_round_boundaries | true |
| spsc_buffer_bytes | 268435456 |
| prefault_producer_buffers | true |
| finish_timeout_ms | 5000 |
| work_wait_min_ms | 1 |
| finish_retry_ms | 1 |
| publish_count | 4294967295 |
| use_write_session | false |
| rigtorp_write_prefetch | false |
| readerwriterqueue_copy_after_zero | {"by_payload_bytes": {"8": false, "16": true, "32": true, "64": false}} |
| spsc_capacity | {"by_payload_bytes": {"8": 33488385, "16": 16743937, "32": 8371713, "64": 4185601}} |
| retry_yield_every | 1024 |
| spsc_idle_spins | 0 |
| spsc_idle_sleep_ns | 12500 |
| timer | auto |
| sample_every | 32 |
| max_samples | 1000000 |
| latency_batch_size | 1000 |
| timer_calibration_samples | 16384 |
| call_batch_size | 256 |
| random_seed | [42, 43, 44] |
| timeout_seconds | 180 |
| buffer_budget_bytes | 536870912 |
| 参数 | 取值 |
|---|---|
| source_thread_id | 0 |
| read_layer1_thread_count | 1 |
| writer_queue_enable_stats | false |
| message_prefix_bytes | 0 |
| writer_count | 1 |
| source_copy_thread_count | 0 |
| callback_thread_count | 1 |
| pool_depth_instrumentation | false |
| callback_signature | (thread_id, data, payload_bytes) |
| callback_business_iterations | 0 |
| unused_fields | source_* / output_* / reader_spin_count / rescan_* / is_scan_current / publish_count: native SPSC does not construct TwoBufQueue layers |
| upstream_unmodified | true |
| requested_native_capacity | {"by_payload_bytes": {"8": 33488385, "16": 16743937, "32": 8371713, "64": 4185601}} |
| native_template | ReaderWriterQueue<Payload,512> |
| copy_policy | {"by_payload_bytes": {"8": "full member copy", "16": "zero initialization then full memcpy", "32": "zero initialization then full memcpy", "64": "full member copy"}} |
| consumer_operation | peek → callback → pop |
完整列出 61 项测试类参数及构造 / 模板参数。消息长度列为统一取值列表;容量条数和已固定的复制配置等随长度变化的值用 by_payload_bytes 对应关系表示,不重复四套参数。
| 参数 | 取值 |
|---|---|
| transport | rigtorp |
| mode | ["throughput", "write_latency"] |
| payload_bytes | [8, 16, 32, 64] |
| messages | 10000000 |
| warmup_messages | 50000 |
| callback_iterations | 0 |
| verify_payload | false |
| prepared_input | true |
| variable_payload | true |
| prepared_input_limit_bytes | 268435456 |
| measure_callback_time | true |
| producer_interval_ns | 0 |
| source_block_size | 65536 |
| source_pool_min | 4096 |
| source_pool_max | 4096 |
| source_queue_capacity | 4096 |
| writer_backpressure | drop |
| writer_spin_count | 1000 |
| writer_wait_timeout_ms | 5000 |
| output_block_size | 1048576 |
| output_frame_capacity | 1024 |
| output_pool_min | 256 |
| output_pool_max | 256 |
| output_queue_capacity | 512 |
| cancel_claim_mode | tail |
| output_mode | spsc |
| output_reader_mode | wait_signal |
| output_reader_count | 1 |
| output_retry_wait_us | 1000 |
| output_enable_stats | false |
| is_scan_current | false |
| reader_spin_count | 1000 |
| rescan_interval_ns | 1000000 |
| rescan_max_interval_ns | 1000000 |
| consumer_cpu | -1 |
| producer_cpu | -1 |
| producer_qos | user_interactive |
| round_storage_bytes | 214748364 |
| fixed_round_boundaries | true |
| spsc_buffer_bytes | 268435456 |
| prefault_producer_buffers | true |
| finish_timeout_ms | 5000 |
| work_wait_min_ms | 1 |
| finish_retry_ms | 1 |
| publish_count | 4294967295 |
| use_write_session | false |
| rigtorp_write_prefetch | true |
| readerwriterqueue_copy_after_zero | false |
| spsc_capacity | {"by_payload_bytes": {"8": 33554415, "16": 16777207, "32": 8388603, "64": 4194301}} |
| retry_yield_every | 1024 |
| spsc_idle_spins | 4000 |
| spsc_idle_sleep_ns | 1000 |
| timer | auto |
| sample_every | 32 |
| max_samples | 1000000 |
| latency_batch_size | 1000 |
| timer_calibration_samples | 16384 |
| call_batch_size | 256 |
| random_seed | [42, 43, 44] |
| timeout_seconds | 180 |
| buffer_budget_bytes | 536870912 |
| 参数 | 取值 |
|---|---|
| source_thread_id | 0 |
| read_layer1_thread_count | 1 |
| writer_queue_enable_stats | false |
| message_prefix_bytes | 0 |
| writer_count | 1 |
| source_copy_thread_count | 0 |
| callback_thread_count | 1 |
| pool_depth_instrumentation | false |
| callback_signature | (thread_id, data, payload_bytes) |
| callback_business_iterations | 0 |
| unused_fields | source_* / output_* / reader_spin_count / rescan_* / is_scan_current / publish_count: native SPSC does not construct TwoBufQueue layers |
| upstream_unmodified | true |
| requested_native_capacity | {"by_payload_bytes": {"8": 33554415, "16": 16777207, "32": 8388603, "64": 4194301}} |
| native_template | rigtorp::SPSCQueue<Payload> |
| copy_policy | member initialization copy + destination write prefetch |
| consumer_operation | front → callback → pop |
完整列出 61 项测试类参数及构造 / 模板参数。消息长度列为统一取值列表;容量条数和已固定的复制配置等随长度变化的值用 by_payload_bytes 对应关系表示,不重复四套参数。
| 参数 | 取值 |
|---|---|
| transport | atomic_queue |
| mode | ["throughput", "write_latency"] |
| payload_bytes | [8, 16, 32, 64] |
| messages | 10000000 |
| warmup_messages | 50000 |
| callback_iterations | 0 |
| verify_payload | false |
| prepared_input | true |
| variable_payload | true |
| prepared_input_limit_bytes | 268435456 |
| measure_callback_time | true |
| producer_interval_ns | 0 |
| source_block_size | 65536 |
| source_pool_min | 4096 |
| source_pool_max | 4096 |
| source_queue_capacity | 4096 |
| writer_backpressure | drop |
| writer_spin_count | 1000 |
| writer_wait_timeout_ms | 5000 |
| output_block_size | 1048576 |
| output_frame_capacity | 1024 |
| output_pool_min | 256 |
| output_pool_max | 256 |
| output_queue_capacity | 512 |
| cancel_claim_mode | tail |
| output_mode | spsc |
| output_reader_mode | wait_signal |
| output_reader_count | 1 |
| output_retry_wait_us | 1000 |
| output_enable_stats | false |
| is_scan_current | false |
| reader_spin_count | 1000 |
| rescan_interval_ns | 1000000 |
| rescan_max_interval_ns | 1000000 |
| consumer_cpu | -1 |
| producer_cpu | -1 |
| producer_qos | user_interactive |
| round_storage_bytes | 214748364 |
| fixed_round_boundaries | true |
| spsc_buffer_bytes | 268435456 |
| prefault_producer_buffers | true |
| finish_timeout_ms | 5000 |
| work_wait_min_ms | 1 |
| finish_retry_ms | 1 |
| publish_count | 4294967295 |
| use_write_session | false |
| rigtorp_write_prefetch | false |
| readerwriterqueue_copy_after_zero | false |
| spsc_capacity | {"by_payload_bytes": {"8": 33554432, "16": 16777216, "32": 8388608, "64": 4194304}} |
| retry_yield_every | 1024 |
| spsc_idle_spins | 2000 |
| spsc_idle_sleep_ns | 10000 |
| timer | auto |
| sample_every | 32 |
| max_samples | 1000000 |
| latency_batch_size | 1000 |
| timer_calibration_samples | 16384 |
| call_batch_size | 256 |
| random_seed | [42, 43, 44] |
| timeout_seconds | 180 |
| buffer_budget_bytes | 536870912 |
| 参数 | 取值 |
|---|---|
| source_thread_id | 0 |
| read_layer1_thread_count | 1 |
| writer_queue_enable_stats | false |
| message_prefix_bytes | 0 |
| writer_count | 1 |
| source_copy_thread_count | 0 |
| callback_thread_count | 1 |
| pool_depth_instrumentation | false |
| callback_signature | (thread_id, data, payload_bytes) |
| callback_business_iterations | 0 |
| unused_fields | source_* / output_* / reader_spin_count / rescan_* / is_scan_current / publish_count: native SPSC does not construct TwoBufQueue layers |
| upstream_unmodified | true |
| requested_native_capacity | {"by_payload_bytes": {"8": 33554432, "16": 16777216, "32": 8388608, "64": 4194304}} |
| native_template | AtomicQueueB2<Payload,std::allocator<Payload>,true,false,true> |
| copy_policy | full member copy |
| consumer_operation | try_pop → callback |
沿用现有结果、负载、复制方式和参数选择规则。
每次 1,000 万条,预热 5 万条;业务回调循环 0;完整负载在写入计时前准备,每条的全部数据字均变化。
每轮上限固定 214,748,364 B,即第二层 256 MiB 的 80%;所有队列采用相同边界,末轮按实际条数结束。
只累计生产者写入时间。轮末交接、尾块发布与回调排空在计时外执行;全部消息仍须消费完成。TwoBufQueue 复制线程与回调线程独立运行。
普通 write 在完整写入后读回首字节;Session 不加该读回。
使用四种长度全部实测过的共同配置。Writer 取三个按 2 倍递增的相邻块大小;原生 SPSC 取三个相邻自旋或等待值。
三个配置的四长度综合总分差异不超过 10%;按重复编号合并的四长度综合分变异系数不超过 20%。每个长度的单项原始结果、波动和邻域变化均保存。
每个配置完整校验通过;三次吞吐与三次延时均成功,零写入失败、零 Writer 背压,延时可解析。参考值的单项变异系数上限仍为 20% / 25% / 40% / 60%。
所有指标取同一套配置;不合并遍历阶段与旧独立复测阶段的结果。这是所测共同参数范围内的最佳综合平台,不能证明全局最优。
macOS-14.4.1-arm64-arm-64bit · arm64 · 8 个逻辑 CPU。
Clang 18.1.8 · Release · -O3 -DNDEBUG · 无 sanitizer。
生产者 user_interactive QoS,未硬绑核;复制和回调线程不绑核。计时器:mach_absolute_time;每组 1,000 次写入。
补测使用原测量二进制,SHA-256 一致;开源头文件、完整负载与复制策略不变。补测前已确认接通电源。
原批共 1,284 次完整校验、9,708 次性能测量;失败运行 0。新增 ReaderWriterQueue 邻域:24 次完整校验、144 次性能测量;失败 0。
三份报告共享同一组原生 SPSC 对照。复制策略按表内标注固定;它与编译器生成代码也会影响结果。
旧逐项选优报告已备份。本页全部四项来自共同参数,参考值固定在补测前;详细运行配置包含 mode、random_seed 的实际值。