Files
Mini-Nav/docs/exps/sw_hw_cam_retrieval_benchmark.md
SikongJueluo 97e53d44f8 feat(hw/sim): distinguish query-only and end-to-end performance cycles in retrieval benchmark
Add explicit separation between query-only cycles (accept→last) and end-to-end cycles
(load + write + noise + queries) in hardware retrieval benchmarks.

- Add query_only_cycles_per_query, load_write_noise_cycles, end_to_end_cycles metrics
- Refactor summarize_query_timings() to use accept_to_last_result_cycles as query-only base
- Add build_hardware_performance() to compute end-to-end performance separately
- Add current_sim_cycle() helper using cocotb get_sim_time
- Update CSV/Markdown outputs and RETRIEVAL_PERF_RESULT log format
- Update documentation to clarify cycle-counting methodology
- Update tests to cover new performance measurement logic
2026-05-29 18:49:05 +08:00

218 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 软件/硬件 CAM 检索基准实验总结
**日期**2026-05-27
**工作区**`/home/sikongjueluo/Projects/Mini-Nav`
**目标**:对比同一组 CAM 检索数据在硬件仿真与软件汉明距离检索下的检索质量,并记录软件检索速度基线与硬件仿真周期性能。
## 1. 实验配置
### 数据集与哈希配置
| 数据集 | 行数 | 查询数 | 类别数 | 哈希宽度 | Top-K |
|---|---:|---:|---:|---:|---:|
| CIFAR-10 | 512 | 128 | 10 | 512 bit | 5 |
| CIFAR-100 | 512 | 128 | 100 | 512 bit | 5 |
数据文件来自:
- `outputs/cam_retrieval_benchmark/datasets/cifar10_hash512_rows512_queries128.npz`
- `outputs/cam_retrieval_benchmark/datasets/cifar100_hash512_rows512_queries128.npz`
`.npz` 内部字段为:
- `rows_words`
- `row_labels`
- `queries_words`
- `query_labels`
软件基准直接复用硬件基准数据格式,将 little-endian `uint64` words 转为 Python `int` 后执行汉明距离 / XNOR-popcount Top-K 检索,避免通过软件 CAM 时序模拟带来额外开销。
### 运行命令
软件检索速度基准:
```bash
just remote "python scripts/sw_retrieval_benchmark.py --dataset outputs/cam_retrieval_benchmark/datasets/cifar10_hash512_rows512_queries128.npz --hash-bits 512 --topk-k 5 --run-id sw_cifar10_hash512_rows512_queries128 && python scripts/sw_retrieval_benchmark.py --dataset outputs/cam_retrieval_benchmark/datasets/cifar100_hash512_rows512_queries128.npz --hash-bits 512 --topk-k 5 --run-id sw_cifar100_hash512_rows512_queries128"
```
硬件噪声扫描数据来自远端已有 Cocotb/Verilator 输出与 `docs/exps/cam_retrieval_noise_sweep_*.md`
硬件检索周期检测命令:
```bash
just cam-test-retrieval-artifact outputs/cam_retrieval_benchmark/datasets/cifar10_hash512_rows512_queries128.npz 512
just cam-test-retrieval-artifact outputs/cam_retrieval_benchmark/datasets/cifar100_hash512_rows512_queries128.npz 512
```
## 2. 软件检索速度与质量
软件路径只计时 Top-K 匹配阶段,不包含 `.npz` 加载、指标聚合和结果写盘。
| 数据集 | Hit@1 | Precision@1 | Std-Recall@1 | Hit@5 | Precision@5 | Std-Recall@5 | Golden Match@5 | ns/query | queries/s |
|---|---:|---:|---:|---:|---:|---:|---:|---:|---:|
| CIFAR-10 | 1.000000 | 1.000000 | 0.019531 | 1.000000 | 1.000000 | 0.097656 | 1.000000 | 205835.281 | 4858.254 |
| CIFAR-100 | 0.695312 | 0.695312 | 0.134635 | 0.867188 | 0.462500 | 0.445052 | 1.000000 | 205868.953 | 4857.459 |
观察:
- 两个数据集的软件吞吐都约为 **4.86k queries/s**
- CIFAR-10 的 Hit@1/Hit@5 均为 1.0,说明在该 512-row 子集上 Top-K 中总能命中同类样本。
- CIFAR-100 的类别更多、每类样本更少Hit@1 降至 0.695312Hit@5 为 0.867188。
- `Golden Match@K = 1.0` 表示软件实现与 `hw/sim/model/ref_model.py::match_topk` 的排序结果一致。
## 3. 无噪声硬件仿真与软件基线一致性
硬件无噪声结果来自 `WRITE_NOISE_EN=0` 的 Cocotb/Verilator 检索基准。该结果用于确认硬件 Top-K 输出与参考模型一致。
| 数据集 | 模式 | Hit@1 | Hit@5 | Precision@5 | Std-Recall@5 | Golden Match@1 | Golden Match@5 |
|---|---|---:|---:|---:|---:|---:|---:|
| CIFAR-10 | software-hamming | 1.000000 | 1.000000 | 1.000000 | 0.097656 | 1.000000 | 1.000000 |
| CIFAR-10 | hardware no-noise | 1.000000 | 1.000000 | 1.000000 | 0.097656 | 1.000000 | 1.000000 |
| CIFAR-100 | software-hamming | 0.695312 | 0.867188 | 0.462500 | 0.445052 | 1.000000 | 1.000000 |
| CIFAR-100 | hardware no-noise | 0.695312 | 0.867188 | 0.462500 | 0.445052 | 1.000000 | 1.000000 |
结论:
- 无噪声硬件仿真与软件汉明距离基线在两个数据集上质量指标一致。
- 这说明 `.npz` 数据加载、little-endian word 转换、硬件 CAM 匹配和软件参考模型在当前配置下是对齐的。
## 4. 写噪声对硬件检索质量的影响
硬件噪声实验使用 `WRITE_NOISE_EN=1`,按 10% 步长扫描 `WRITE_NOISE_RATE_NUM / 100`。以下表格保留主要指标 Hit@1、Hit@5 与 Golden Match@K
### CIFAR-10 噪声扫描
| 写噪声率 | Hit@1 | Hit@5 | Golden Match@1 | Golden Match@5 |
|---:|---:|---:|---:|---:|
| 0% | 1.000000 | 1.000000 | 1.000000 | 1.000000 |
| 10% | 1.000000 | 1.000000 | 0.507812 | 0.000000 |
| 20% | 1.000000 | 1.000000 | 0.234375 | 0.000000 |
| 30% | 0.992188 | 1.000000 | 0.164062 | 0.000000 |
| 40% | 0.984375 | 1.000000 | 0.093750 | 0.000000 |
| 50% | 0.257812 | 0.750000 | 0.023438 | 0.000000 |
| 60% | 0.000000 | 0.015625 | 0.000000 | 0.000000 |
| 70% | 0.000000 | 0.000000 | 0.000000 | 0.000000 |
| 80% | 0.000000 | 0.000000 | 0.000000 | 0.000000 |
| 90% | 0.000000 | 0.000000 | 0.000000 | 0.000000 |
| 100% | 0.000000 | 0.000000 | 0.000000 | 0.000000 |
观察:
- CIFAR-10 在 0%40% 写噪声下 Hit@5 仍保持 1.0。
- Golden Match@5 从 10% 噪声开始降为 0说明 Top-5 的精确排序对噪声非常敏感。
- 50% 噪声是明显拐点Hit@1 降至 0.257812Hit@5 降至 0.75。
- 60% 以后检索基本失效。
### CIFAR-100 噪声扫描
| 写噪声率 | Hit@1 | Hit@5 | Golden Match@1 | Golden Match@5 |
|---:|---:|---:|---:|---:|
| 0% | 0.695312 | 0.867188 | 1.000000 | 1.000000 |
| 10% | 0.585938 | 0.812500 | 0.593750 | 0.023438 |
| 20% | 0.562500 | 0.742188 | 0.460938 | 0.000000 |
| 30% | 0.460938 | 0.640625 | 0.304688 | 0.000000 |
| 40% | 0.234375 | 0.460938 | 0.101562 | 0.000000 |
| 50% | 0.000000 | 0.062500 | 0.000000 | 0.000000 |
| 60% | 0.000000 | 0.007812 | 0.000000 | 0.000000 |
| 70% | 0.000000 | 0.007812 | 0.000000 | 0.000000 |
| 80% | 0.000000 | 0.000000 | 0.000000 | 0.000000 |
| 90% | 0.000000 | 0.000000 | 0.000000 | 0.000000 |
| 100% | 0.000000 | 0.000000 | 0.000000 | 0.000000 |
观察:
- CIFAR-100 对噪声更敏感10% 噪声时 Hit@1 从 0.695312 降至 0.585938Hit@5 从 0.867188 降至 0.812500。
- 40% 噪声时 Hit@5 已降至 0.460938。
- 50% 噪声后检索基本不可用。
- 与 CIFAR-10 相同Golden Match@5 在低噪声下也迅速接近 0说明精确排序比类别命中率更脆弱。
## 5. 硬件检索周期性能
本次已将硬件周期检测合并进真实 `.npz` 检索数据集的 Cocotb/Verilator
benchmark。实现位置
- `hw/sim/tests/top/utils.py::query_topk_once_with_latency`
- `hw/sim/benchmarks/retrieval/test_retrieval_benchmark.py::cam_retrieval_benchmark`
周期口径如下。本节只报告Cocotb/Verilator仿真周期不将cycle直接换算为ns或queries/s。
| 指标 | 含义 |
|---|---|
| `query_only_cycles_per_query` | 主指标。每个query从`query_valid && query_ready`握手成功的时钟沿,到对应`result_valid && result_ready && result_last`完成的平均周期数。 |
| `query_only_total_cycles` | 所有query-only事务周期之和不包含装载、写入、噪声注入和查询间统计代码。 |
| `query_only_queries_per_cycle` | `num_queries / query_only_total_cycles`。 |
| `load_write_noise_cycles` | 写入CAM行以及可选写噪声注入阶段的周期数。无噪声模式下仍包含CAM行写入周期。 |
| `end_to_end_cycles` | 从开始写入数据集到最后一个query完成的完整benchmark硬件仿真周期数。 |
| `end_to_end_queries_per_cycle` | `num_queries / end_to_end_cycles`。 |
| `accept_to_first_result_cycles` | query被接受后到首个结果beat完成握手的平均周期数。 |
| `accept_to_last_result_cycles` | query被接受后`result_last`结果beat完成握手的平均周期数。 |
| `cycles_per_query``total_query_cycles``queries_per_cycle` | 兼容旧字段当前均为query-only口径不代表end-to-end。 |
选择query-only的`accept→last`作为主cycles/query是因为Top-K检索只有在串行结果流输出到`result_last`并被接收后才算完整完成;仅用首个`result_valid`会低估实际Top-K查询事务成本。`load_write_noise_cycles``end_to_end_cycles`单独报告避免把非查询阶段混入query-only性能。
### 无噪声硬件周期结果
配置512 rows×128 queries×512-bit hash`TOPK_K=5``LANES=8`
`WRITE_NOISE_EN=0`
| 数据集 | 模式 | 查询数 | query-only cycles/query | query-only total cycles | query-only queries/cycle | load/write/noise cycles | end-to-end cycles | end-to-end cycles/query | end-to-end queries/cycle | accept→first | accept→last | 状态 |
|---|---|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---|
| CIFAR-10 | hardware no-noise | 128 | 1031.000000 | 131968 | 0.000969932 | 1024 | 133628 | 1043.968750 | 0.000957883 | 1027.000000 | 1031.000000 | pass |
| CIFAR-100 | hardware no-noise | 128 | 1031.000000 | 131968 | 0.000969932 | 1024 | 133628 | 1043.968750 | 0.000957883 | 1027.000000 | 1031.000000 | pass |
对应日志标记:
```text
RETRIEVAL_PERF_RESULT mode=no_noise num_queries=128 query_only_cycles_per_query=1031.000000 query_only_total_cycles=131968 query_only_queries_per_cycle=0.000969932 load_write_noise_cycles=1024 end_to_end_cycles=133628 end_to_end_cycles_per_query=1043.968750 end_to_end_queries_per_cycle=0.000957883 cycles_per_query=1031.000000 accept_to_first_result_cycles=1027.000000 accept_to_last_result_cycles=1031.000000 total_query_cycles=131968 queries_per_cycle=0.000969932 status=pass
```
该结果说明:在当前 `NUM_ROWS=512, LANES=8, TOPK_K=5` 的硬件仿真配置下,
一次完整Top-K查询事务的query-only成本为**1031cycles/query**。首个结果beat约在1027cycles后出现完整Top-K输出额外消耗约4cycles。完整benchmark端到端口径为**1043.968750cycles/query**其中数据写入阶段为1024cycles。
> 注:以上数据来自 Verilator/Cocotb 仿真,不是 FPGA 板上实测。它可用于
> 架构级周期趋势分析,但不能直接等同于板级频率、吞吐或端到端系统延迟。
## 6. 指标解释
| 指标 | 含义 |
|---|---|
| Hit@K / `recall@k` | 每个 query 的 Top-K 中是否至少出现一个同类样本,然后对 query 取平均。 |
| Precision@K / `macro_precision` | 每个 query 的 Top-K 中同类样本比例,即 `tp / k`,再对 query 取平均。 |
| Std-Recall@K / `retrieval_recall` | 每个 query 检出的同类样本数占数据库中所有同类样本数的比例,即 `tp / |relevant|`,再取平均。 |
| Std-F1@K / `macro_f1` | 使用 Precision@K 与 Std-Recall@K 计算的 F1。 |
| Golden Match@K / `exact_match_rate` | Top-K row index 列表是否与参考模型完全一致。该指标比 Hit@K 更严格。 |
| `ns_per_query` | 软件 Top-K 匹配阶段平均耗时;不含加载和写盘。 |
| `queries_per_second` | 软件 Top-K 匹配阶段吞吐率。 |
| `query_only_cycles_per_query` | 硬件仿真中一次完整Top-K查询事务的平均周期数采用`query_valid && query_ready``result_last`完成握手口径。 |
| `query_only_queries_per_cycle` | 硬件仿真中完成query数除以query-only总事务周期数。 |
| `load_write_noise_cycles` | CAM行装载、写入及可选写噪声注入阶段周期数。 |
| `end_to_end_cycles` | 从开始写入数据到最后一个query完成的完整benchmark硬件仿真周期数。 |
| `end_to_end_queries_per_cycle` | 硬件仿真中完成query数除以end-to-end总周期数。 |
## 7. 当前结论
1. **软件汉明距离基线已可作为硬件 CAM 检索的功能参考。**
在无噪声条件下,硬件仿真和软件基线的质量指标及 Golden Match 均一致。
2. **当前软件基线速度约为 4.86k queries/s。**
该结果来自 Python integer brute-force Hamming scan数据规模为 512 rows × 128 queries × 512 bits。
3. **硬件检索质量基准现在显式拆分query-only与end-to-end周期。**
在CIFAR-10和CIFAR-100的512-row/128-query无噪声配置下完整Top-K查询事务均为**1031cycles/query**,首个结果为**1027cycles/query**;写入阶段为**1024cycles**,端到端为**1043.968750cycles/query**。
4. **写噪声对精确排序影响显著。**
即使 Hit@K 保持较高Golden Match@K 也会快速下降,说明噪声首先破坏精确排序,再进一步破坏类别命中。
5. **CIFAR-100 比 CIFAR-10 更能体现检索难度。**
在无噪声下 CIFAR-100 的 Hit@1/Hit@5 分别为 0.695312/0.867188,明显低于 CIFAR-10 的 1.0/1.0,更适合作为后续检索质量对比主数据集。
## 8. 后续建议
1.`docs/exps` 中继续维护:
- 软件检索速度表;
- 硬件无噪声一致性表;
- 硬件噪声鲁棒性表;
- 硬件query-only、load/write/noise、end-to-end周期表。
2. 对软件基线补充 NumPy/PyTorch vectorized Hamming scan以区分“朴素 Python baseline”和“优化软件 baseline”。
3. 增加 `NUM_ROWS` sweep例如 512、1024、2048、4096 rows观察软件 brute-force scan 的线性增长趋势。