| # 实验计划 |
| |
| --- |
| |
| ## 一、实验环境 |
| |
| ### 硬件平台(fit39) |
| |
| | 项目 | 配置 | |
| |------|------| |
| | CPU | Intel Core i7-10700 @ 2.90 GHz, 8 核 16 线程, Turbo 4.8 GHz | |
| | 缓存 | L1d 256 KiB / L1i 256 KiB / L2 2 MiB / L3 16 MiB | |
| | SIMD | SSE4.2, AVX2 (256-bit) | |
| | 内存 | 32 GB DDR4 | |
| | 存储 | Samsung 970 EVO Plus 250 GB NVMe SSD + ST 10 TB HDD | |
| | 操作系统 | Ubuntu 20.04.6 LTS, Linux 5.4.0 | |
| | 编译器 | GCC 9.4.0 | |
| | 构建 | CMake 3.16.3, Release (`-O2`) | |
| | Python | 3.8.10 + PyArrow + Pandas | |
| |
| ### 编译配置矩阵 |
| |
| | 编号 | THREADS | SIMD | MEM_STAT | 用途 | |
| |:----:|:-------:|:----:|:--------:|------| |
| | C1 | OFF | OFF | OFF | 串行 + 标量基线 | |
| | C2 | ON | OFF | OFF | 仅多线程 | |
| | C3 | OFF | ON | OFF | 仅 SIMD | |
| | C4 | ON | ON | OFF | 多线程 + SIMD(生产配置) | |
| | C5 | ON | ON | ON | 生产 + 内存追踪 | |
| |
| --- |
| |
| ## 二、统一数据集 |
| |
| ### 基线负载(W0) |
| |
| | 项目 | 值 | |
| |------|-----| |
| | 总行数 | 200M | |
| | 设备数 | 10(每设备 20M 行) | |
| | TAG 列 | 2 × STRING | |
| | FIELD 列 | 8(INT32 × 2, INT64 × 2, FLOAT × 2, DOUBLE × 2) | |
| | 编码 | TS_2DIFF(整型), GORILLA(浮点) | |
| | 压缩 | SNAPPY | |
| | Batch | 65,536 行 | |
| | 写入模式 | 顺序写入 + 混合写入 | |
| |
| ### 变化负载 |
| |
| | 编号 | 变化维度 | 值 | 用途 | |
| |:----:|---------|-----|------| |
| | W1 | FIELD 列数 | 4 / 8 / 16 | 第四章并行化、第六章端到端 | |
| | W2 | 压缩算法 | LZ4 / SNAPPY / ZSTD | 第四章加速比 | |
| | W3 | 时间过滤选择率 | 1% / 10% / 50% / 90% / 100% | 第五章过滤、第六章端到端 | |
| | W4 | 内存预算 | 8 / 16 / 32 / 64 / 128 MB | 第三章内存约束 | |
| | W5 | batch_size | 1K / 4K / 16K / 64K | 第三章读取内存 | |
| | W6 | 线程数 | 1 / 2 / 4 / 8 | 第四章并行化 | |
| |
| > 每个实验只变化一个维度,其余保持基线 W0。 |
| |
| --- |
| |
| ## 三、第三章实验:基于内存建模的 TsFile 读写优化 |
| |
| ### E3-1 写入内存模型验证 |
| |
| - **编译**:C5(开启 MEM_STAT) |
| - **负载**:W0 基线 |
| - **方法**:ModStat 逐模块追踪,每 50 万行采集一次 |
| |
| #### E3-1a 无 flush 基线(动机实验) |
| |
| - **配置**:关闭自动 flush(memory_threshold 设为极大值,如 100 GB),不手动调用 flush |
| - **目的**:展示不做内存管理时内存如何不可控增长,作为后续优化的对照基线 |
| - **产出**: |
| - **图 F3-0**:无 flush 写入内存曲线——$M_{\text{data}}$ 和 $M_{\text{meta}}$ 均单调递增,总内存持续攀升直至 OOM 或写完 |
| - **预期**:内存线性增长不回落,直观说明"不管理就会爆" |
| |
| #### E3-1b 有 flush 写入(主实验) |
| |
| - **配置**:W0 基线,memory_threshold = 50 MB |
| - **产出**: |
| - **图 F3-1**:顺序写入模式内存曲线(各 AllocModID 随行数变化,锯齿形) |
| - **图 F3-2**:混合写入模式内存曲线 |
| - **表 T3-1**:各模块内存分布(CW_PAGES_DATA / DEFAULT / TABLET / META 等) |
| - **表 T3-2**:顺序写入 flush 事件(触发行数、flush 前后内存、释放量) |
| - **表 T3-3**:混合写入 flush 事件 |
| - **表 T3-4**:两种写入模式对比(残留内存、flush 次数、PAGE_WRITER 峰值) |
| |
| > F3-0 与 F3-1/F3-2 形成对照:无 flush 时内存单调递增,有 flush 时 $M_{\text{data}}$ 呈锯齿但 $M_{\text{meta}}$ 仍递增——引出文件轮转的必要性。 |
| |
| ### E3-2 写入内存模型精度 |
| |
| - **编译**:C5 |
| - **负载**:50 设备 × 50 FIELD(INT32)× 100K 行,变化 batch 大小 |
| - **产出**: |
| - **表 T3-5**:batch_size(5K/6K/8K/10K)× 实测内存 / 公式估算 / 误差 |
| |
| ### E3-3 读取内存模型验证 |
| |
| - **编译**:C5 |
| - **负载**:W0 文件,变化列数(W1: 1/4/8/16)× batch_size(W5: 1K/4K/16K/64K) |
| - **产出**: |
| - **表 T3-6**:列数 × batch_size 矩阵,每格为实测峰值 / 公式值 / 误差 |
| - **图 F3-3**:折线图,x = batch_size,y = 峰值内存,每条线一个列数,虚线为公式预测 |
| |
| ### E3-4 不同内存预算下的写入性能 |
| |
| - **编译**:C4 |
| - **负载**:W0 基线,变化内存预算(W4: 8/16/32/64/128 MB) |
| - **对比组**:(a) MemConstrainedWriter 自动 (b) 默认配置 (c) 无限制 |
| - **产出**: |
| - **表 T3-7**:各预算下写入吞吐(M rows/s)、flush 次数、文件轮转次数、峰值内存 |
| - **图 F3-4**:柱状图,x = 内存预算,y = 吞吐,三组对比 |
| |
| ### 第三章产出汇总 |
| |
| | 编号 | 类型 | 描述 | 状态 | |
| |------|------|------|:----:| |
| | F3-0 | 图 | 无 flush 基线内存曲线(动机对照) | TODO | |
| | F3-1 | 图 | 顺序写入内存曲线(有 flush) | ✅ 已有 | |
| | F3-2 | 图 | 混合写入内存曲线(有 flush) | ✅ 已有 | |
| | F3-3 | 图 | 读取内存 vs batch_size 折线图 | TODO | |
| | F3-4 | 图 | 不同内存预算写入吞吐对比 | TODO | |
| | T3-1 | 表 | 写入各模块内存分布 | ✅ 已有 | |
| | T3-2 | 表 | 顺序写入 flush 事件 | ✅ 已有 | |
| | T3-3 | 表 | 混合写入 flush 事件 | ✅ 已有 | |
| | T3-4 | 表 | 两种写入模式对比 | ✅ 已有 | |
| | T3-5 | 表 | 写入内存模型精度验证 | ✅ 已有 | |
| | T3-6 | 表 | 读取内存模型精度验证 | TODO | |
| | T3-7 | 表 | 不同内存预算写入性能 | TODO | |
| |
| --- |
| |
| ## 四、第四章实验:面向列的多线程读写并行化 |
| |
| ### E4-1 写入并行加速比 |
| |
| - **编译**:C2(仅多线程,关闭 SIMD 以隔离变量) |
| - **负载**:W0 基线,变化列数(W1)× 线程数(W6)× 压缩算法(W2) |
| - **产出**: |
| - **表 T4-1**:写入吞吐矩阵(列数 × 线程数),SNAPPY |
| - **表 T4-2**:写入吞吐矩阵(列数 × 线程数),LZ4 |
| - **表 T4-3**:写入吞吐矩阵(列数 × 线程数),ZSTD |
| - **图 F4-1**:写入加速比曲线,x = 线程数,实线 = 实测,虚线 = Amdahl 理论,按压缩算法分子图 |
| |
| ### E4-2 读取并行加速比 |
| |
| - **编译**:C2 |
| - **负载**:同 E4-1 |
| - **产出**: |
| - **表 T4-4**:读取吞吐矩阵(列数 × 线程数),SNAPPY |
| - **表 T4-5**:读取吞吐矩阵(列数 × 线程数),LZ4 |
| - **表 T4-6**:读取吞吐矩阵(列数 × 线程数),ZSTD |
| - **图 F4-2**:读取加速比曲线,格式同 F4-1 |
| |
| ### E4-3 串行占比 α 实测 |
| |
| - **来源**:从 E4-1 / E4-2 的 1 线程 vs 多线程数据反推 |
| - **产出**: |
| - **表 T4-7**:压缩算法 × 路径(读/写)的实测 α 值 vs 正文估算值 vs 偏差 |
| |
| ### E4-4 多线程 + SIMD 叠加 |
| |
| - **编译**:C1 / C2 / C3 / C4 四组 |
| - **负载**:W0 基线,8 列,4 线程,ZSTD |
| - **产出**: |
| - **表 T4-8**:四组配置的读写吞吐、加速比;标注各自乘积 vs 实际叠加 |
| |
| ### 第四章产出汇总 |
| |
| | 编号 | 类型 | 描述 | 状态 | |
| |------|------|------|:----:| |
| | F4-1 | 图 | 写入加速比曲线(实测 vs Amdahl) | TODO | |
| | F4-2 | 图 | 读取加速比曲线(实测 vs Amdahl) | TODO | |
| | T4-1~T4-3 | 表 | 写入吞吐矩阵(3 种压缩) | TODO | |
| | T4-4~T4-6 | 表 | 读取吞吐矩阵(3 种压缩) | TODO | |
| | T4-7 | 表 | α 实测 vs 估算 | TODO | |
| | T4-8 | 表 | 多线程 + SIMD 叠加效果 | TODO | |
| |
| --- |
| |
| ## 五、第五章实验:SIMD 向量化编解码与过滤加速 |
| |
| ### E5-1 编解码吞吐对比 |
| |
| - **层面**:解码器微基准(绕过文件 I/O,排除 I/O 干扰) |
| - **编译**:C1(标量)vs C3(仅 SIMD) |
| - **负载**:W0 基线,单线程 |
| - **产出**: |
| - **表 T5-1**:数据类型(INT32/INT64/FLOAT/DOUBLE)× SIMD ON/OFF 的编码吞吐 + 加速比 |
| - **表 T5-2**:数据类型 × SIMD ON/OFF 的解码吞吐 + 加速比 |
| |
| ### E5-2 时间过滤 + 延迟物化 |
| |
| - **层面**:TsFile 端到端(含 I/O + 解压缩 + 解码 + 过滤),数据 warm cache |
| - **编译**:C1(标量 + 提前物化 + 方案 A)vs C3(SIMD + 延迟物化 + 方案 C) |
| - **负载**:W0 基线(规则采样,bit_width_≈0),单线程,变化选择率(W3: 1%/10%/50%/90%/100%) |
| - **埋点**:`blocks_total`、`blocks_skipped_by_peek`、`blocks_decoded`(用于辅助分析) |
| - **产出**: |
| - **表 T5-3**:选择率 × 配置的端到端读取吞吐 + 加速比 |
| - **图 F5-1**:x = 选择率,y = 读取吞吐,C1/C3 两条曲线 |
| - **图 F5-2**:x = 选择率,y = 实际解码行数/总行数(延迟物化收益) |
| - **注**:W0 为规则采样(bit_width_≈0),方案 A/C 结果相同;不规则采样下方案 C 的 |
| 独立收益由 E5-4 专门量化 |
| |
| ### E5-3 跨平台对比 |
| |
| - **层面**:解码器微基准(复用 E5-1/E5-2 程序) |
| - **编译**:C3(SIMD ON)vs C1(标量回退),均在 fit39 上 |
| - **说明**:fit39 为 x86 AVX2 平台;ARM NEON 对比可在 Mac (Apple Silicon) 上补充,或仅做 AVX2 vs 标量 |
| - **产出**: |
| - **表 T5-4**:AVX2 / 标量 × 操作(编码/解码/过滤)的吞吐和加速比 |
| |
| ### E5-4 块级过滤精度(方案 A vs 方案 C) |
| |
| - **层面**:解码器微基准(直接操作 ByteStream,无文件 I/O) |
| - **编译**:同一程序,编译宏 `USE_LOOKAHEAD` ON/OFF 切换方案 |
| - **负载**:内存中生成的不规则采样数据,变化 `target_bw`(0/4/8/12) |
| - **两个子实验**: |
| |
| **E5-4a(skip rate)**:构造查询起始时间落在幻影区间,统计两种方案的 phantom block 数量 |
| - **产出**:**表 T5-5**(skip rate × bit_width_ × 方案)、**图 F5-3**(phantom block 柱状图) |
| |
| **E5-4b(查询延迟)**:标准 10% 选择率查询,重复 1000 次取中位数 |
| - **产出**:**表 T5-6**(延迟 × bit_width_ × 方案 A/C) |
| |
| - **预期**: |
| - bit_width_=0:A=C(验证退化路径) |
| - bit_width_=8:方案 A 产生约 250 个 phantom block/1000,方案 C 为 0 |
| - 幻影区间宽度与 `2^bit_width_` 成正比(实验验证理论公式) |
| |
| ### 第五章产出汇总 |
| |
| | 编号 | 类型 | 描述 | 实验 | 状态 | |
| |------|------|------|------|:----:| |
| | F5-1 | 图 | 时间过滤吞吐 vs 选择率 | E5-2 | TODO | |
| | F5-2 | 图 | 延迟物化解码比例 vs 选择率 | E5-2 | TODO | |
| | F5-3 | 图 | phantom block 数 vs bit_width_(A vs C)| E5-4a | TODO | |
| | T5-1 | 表 | 编码吞吐 SIMD ON/OFF | E5-1 | TODO | |
| | T5-2 | 表 | 解码吞吐 SIMD ON/OFF | E5-1 | TODO | |
| | T5-3 | 表 | 时间过滤吞吐 × 选择率 | E5-2 | TODO | |
| | T5-4 | 表 | AVX2 vs 标量跨平台对比 | E5-3 | TODO | |
| | T5-5 | 表 | skip rate × bit_width_(方案 A vs C)| E5-4a | TODO | |
| | T5-6 | 表 | 查询延迟 × bit_width_(方案 A vs C)| E5-4b | TODO | |
| |
| --- |
| |
| ## 六、第六章实验:面向 AI 负载的数据接口设计 |
| |
| ### E6-1 TsFile vs Parquet 端到端读取 |
| |
| - **编译**:C4(生产配置) |
| - **负载**:W0 基线,变化列数(W1: 4/8/16)× 选择率(W3: 10%/50%/100%) |
| - **方法**:Python 层 `tsfile.to_dataframe()` vs `pyarrow.parquet.read_table()` |
| - **产出**: |
| - **表 T6-1**:列数 × 选择率 × 格式 的读取吞吐(M rows/s) |
| |
| ### E6-2 优化透传效果 |
| |
| - **编译**:C1 / C2 / C3 / C4 四组 |
| - **负载**:W0 基线,8 列,50% 选择率 |
| - **方法**:Python `to_dataframe()` 端到端 |
| - **产出**: |
| - **表 T6-2**:各优化组合的吞吐 / 加速比 / 内存峰值 |
| |
| ### E6-3 流式迭代内存控制 |
| |
| - **编译**:C4 |
| - **负载**:三种文件大小(~100 MB / ~1 GB / ~10 GB),变化 batch_size(4K/16K/64K) |
| - **方法**:`to_dataframe(as_iterator=True)`,监测 Python 进程 RSS |
| - **产出**: |
| - **图 F6-1**:x = 文件大小,y = 内存峰值,每条线一个 batch_size(预期水平线) |
| |
| ### 第六章产出汇总 |
| |
| | 编号 | 类型 | 描述 | 状态 | |
| |------|------|------|:----:| |
| | F6-1 | 图 | 流式迭代内存峰值 vs 文件大小 | TODO | |
| | T6-1 | 表 | TsFile vs Parquet 端到端吞吐 | TODO | |
| | T6-2 | 表 | 优化透传效果(逐步开启) | TODO | |
| |
| --- |
| |
| ## 七、执行计划 |
| |
| ### 阶段一:准备 |
| |
| 1. 在 fit39 上构建 C1–C5 共 5 个编译目录 |
| 2. 用 C5 生成 W0 基线数据文件(200M 行写入 → TsFile) |
| 3. 用同一份数据转存 Parquet 文件(第六章对比用) |
| 4. `pip3 install pyarrow pandas` |
| |
| ### 阶段二:按章跑实验 |
| |
| ``` |
| 第三章(C5 为主) |
| E3-1 写入内存模型验证 → F3-1, F3-2, T3-1~T3-4 (已有,确认可复现) |
| E3-2 写入内存模型精度 → T3-5 (已有) |
| E3-3 读取内存模型验证 → F3-3, T3-6 |
| E3-4 不同内存预算写入性能 → F3-4, T3-7 |
| |
| 第五章(C1 vs C3,E5-4 另用编译宏) |
| E5-4 块级过滤方案 A vs C → F5-3, T5-5, T5-6 ← 优先,验证方案 C 贡献 |
| E5-1 编解码吞吐对比 → T5-1, T5-2 |
| E5-2 时间过滤 + 延迟物化 → F5-1, F5-2, T5-3 |
| E5-3 跨平台对比 → T5-4 |
| |
| 第四章(C2 为主,C1/C3/C4 补充) |
| E4-1 写入并行加速比 → F4-1, T4-1~T4-3 |
| E4-2 读取并行加速比 → F4-2, T4-4~T4-6 |
| E4-3 α 实测 → T4-7 |
| E4-4 多线程 + SIMD 叠加 → T4-8 |
| |
| 第六章(C4,Python 层) |
| E6-1 TsFile vs Parquet → T6-1 |
| E6-2 优化透传效果 → T6-2 |
| E6-3 流式迭代内存控制 → F6-1 |
| ``` |
| |
| ### 阶段三:填表 |
| |
| 把实验数据填入各章 LaTeX 表格和图。 |
| |
| --- |
| |
| ## 八、全量产出清单 |
| |
| | 章 | 图 | 表 | 已有 | TODO | |
| |:--:|:--:|:--:|:----:|:----:| |
| | 3 | 5 | 7 | 2 图 + 5 表 | 3 图 + 2 表 | |
| | 4 | 2 | 8 | 0 | 2 图 + 8 表 | |
| | 5 | 2 | 4 | 0 | 2 图 + 4 表 | |
| | 6 | 1 | 2 | 0 | 1 图 + 2 表 | |
| | **合计** | **10** | **21** | **7** | **8 图 + 16 表** | |