> For AI agents: the complete documentation index is available at https://shijin.space/llms.txt, the full documentation bundle is available at https://shijin.space/llms-full.txt.

# 实践经验

# MOSAIC-Sieve 实践经验

## 异步批次流水线

[《架构设计》](https://shijin.space/projects/mosaic-sieve-architecture/index.md)说明了数据从存储进入计算、再回到向量池的路径。实际执行时，如果每批都依次完成数据准备、设备计算和结果收集，GPU 会在主机整理数据时等待，主机也会在 GPU 计算时等待。

这里以当前 CUDA 搜索路径为例。将工作拆成批次，并为同时在途的批次保留各自的缓冲，就可以在 GPU 处理当前批时，准备下一批，或收集已完成批次的结果。

### 让不同批次交叠

下面用 A、B、C 三个批次和两个批次槽位说明。槽位保存一批任务使用的输入、结果及状态，直到这批任务的相关使用全部结束。

```mermaid
sequenceDiagram
    participant H as Host workers
    participant S as Batch slots
    participant G as GPU
    H->>S: Prepare A in Slot 1
    S->>G: Submit A
    par Device work
        G->>G: Transfer and compute A
    and Host work
        H->>S: Prepare B in Slot 2
        S->>G: Submit B when resources allow
    end
    G-->>S: A results ready
    par Device work
        G->>G: Transfer and compute B
    and Host work
        H->>S: Collect A candidates
        S-->>H: A fully consumed
        Note over H,S: All users finished<br/>Release A views
        H->>S: Reuse Slot 1 to prepare C
    end
    S->>G: Submit C
```

GPU 处理 A 时，主机准备 B；B 提交后，主机收集 A 的候选。A 完全处理结束后，原槽位可以用于准备 C，从而继续与 B 的设备计算交叠。

图中展示的是一种简化的批次时序。B 在输入准备完成且执行资源可用时即可提交，无须等待 A 整批计算结束。当前实现的数据准备与结果收集共用主机工作线程，两者轮流推进，并与 GPU 工作交叠。支持流式候选输出时，还可以在整批搜索结束前，先收集已经回传的部分结果。

### 缓冲何时可以复用

复用的条件是：**所有仍会访问这份数据的任务都已结束。** 任务提交完成、数据上传完成或 GPU 计算完成，分别只代表某个阶段结束。

候选可能通过索引引用原向量，后续恢复、检查或结果处理仍需要读取输入数据。因此，一个批次槽位要等设备工作、候选消费及相关结果处理全部结束，才能释放它借用的源数据，并交给下一批。

工作区可以保留已经分配的容量，供下一批覆盖使用；旧批次借用的向量与索引视图则应及时归还。如果源数据被多个批次共享，还要等最后一个使用者结束，才能改写或回收源存储。

## 先看整条流水线，再定位瓶颈

流水线的目标是缩短完成同一份工作的总时间。观察时先看完整任务耗时和单位时间完成的工作量，再用各阶段耗时、等待与积压解释原因。这里的判断是排查线索，具体瓶颈仍要通过对照实验确认。

准备、传输、计算与收集可能交叠，各阶段累计耗时不能直接相加当作总耗时。异步提交返回也不代表设备工作完成；比较总时间时，要覆盖最后一批结果处理结束。为测量而逐批强制等待，则可能破坏原本的交叠。计时背景可参见 [CUDA 性能计时说明](https://docs.nvidia.com/cuda/cuda-c-best-practices-guide/index.html#timing)。

- **数据准备跟不上**：设备经常等输入，尚未准备好的批次较多。先区分是在等外存读取，还是主机在整理向量、生成中心和组织索引。许多小批次造成重复准备时，可以尝试适当增大批次；若受限于持续的读盘或内存访问，增加在途批次通常只能缓解短时等待。
- **传输拖慢推进**：输入已经准备好，设备却仍在等上传，或结果回传迟迟未结束。这里的传输指主机与设备之间的数据移动，外存读取归入数据准备。如果是大量小传输，可尝试合并批次；如果传输通路已持续繁忙，应优先减少重复搬运、复用已有数据。增加并发能否改善，要看硬件与调度是否允许传输和计算交叠。
- **设备计算阶段占主导**：输入供应充足，计算任务持续运行，而准备和收集能及时完成。若小批次使设备工作零碎，可以增大批次；若设备已被充分利用，再增加在途批次往往只会延长排队。计算阶段耗时长也可能来自设备内部访存，不能仅凭 GPU 利用率就判定算术运算是瓶颈。进一步分析 kernel 内部的数据加载、点积计算、筛选与输出，可参见[《CUDA 与 Tensor Core 编程》](https://shijin.space/projects/mosaic-sieve-cuda-tensor-cores/index.md)。
- **结果收集跟不上**：已完成的候选持续积压，旧槽位迟迟不能释放，进而挡住后续提交。此时应检查候选恢复、去重、接纳和写入的成本。适当减小批次可能减轻结果突发和峰值占用，但持续的处理能力不足仍需优化收集过程；继续增加在途批次会让更多输入和结果滞留。

当前 CUDA 路径的数据准备与结果收集共用主机工作线程。即使两者单独看都不长，合起来也可能无法跟上设备速度；结果处理过久，还会推迟下一批输入准备。

## 分别调整批次大小与在途批次数

批次大小决定一次提交多少工作，在途批次数决定同时保留多少批尚未完全结束的工作。这是两个调节方向，但实际批次还受到任务边界、缓冲预算和缓存规划约束；增加槽位时，每个槽位可用的空间也可能变化。对照实验应记录实际批次大小和峰值占用。

调节批次时，先保持筛法的桶划分和搜索条件不变，只改变工作如何打包、提交。改变桶的大小可能同时改变候选组合与搜索工作量，不能把它当成单纯的批次调节。

1. **先确定可用的缓冲预算。** 除输入外，还要留出索引、设备工作区和候选结果空间。批次变大时，结果占用未必按输入大小同比增长，因此要同时观察主机内存和显存峰值。
2. **固定在途批次数，调整批次大小。** 从能够稳定运行的配置开始，根据前述瓶颈选择增大或减小批次，比较完整任务耗时。小批次的重复准备、传输和提交开销突出时尝试增大；结果突发、长批次拖尾或峰值占用突出时尝试减小。保留能够改善整体速度且资源占用可接受的配置。
3. **固定批次大小，再调整在途批次数。** 若时间线上仍有等待空档，且有可交叠的独立工作和足够缓冲，可逐步增加在途批次。若吞吐不再改善，或者只增加排队和内存占用，就停止增加。预算受限时，两者需要搭配调整，但每次对照尽量只改变一项。

## 用完整结果验证调整

比较时保持输入、筛法条件、后端、存储模式和硬件布局一致，重复运行，并区分初始化、文件缓存等因素对测量的影响。既观察稳定处理期间的速度，也检查整次任务结束所需的时间，避免忽略启动和最后几批收尾的成本。

同时确认实际搜索工作量和结果质量没有退化，检查是否出现容量溢出、候选丢弃或任务未完成。少做了工作得到的“加速”，不能作为批次调节有效的依据。

最终保留的是在资源预算内、能够稳定完成同等工作的较快配置。关于减少传输与合并小传输的一般原则，可参见 [CUDA 主机与设备间的数据传输](https://docs.nvidia.com/cuda/cuda-c-best-practices-guide/index.html#data-transfer-between-host-and-device)。

资料依据：MOSAIC-Sieve v3 的 CUDA 搜索流水线、任务输入缓冲及借用管理实现。核对版本：`1b22e06cceed`；整理日期：2026-10-20。

## 引用此笔记

- [项目概览](https://shijin.space/projects/mosaic-sieve/index.md)
- [架构设计](https://shijin.space/projects/mosaic-sieve-architecture/index.md)
- [CUDA 与 Tensor Core 编程](https://shijin.space/projects/mosaic-sieve-cuda-tensor-cores/index.md)
