Rust in Everything
基于 tenferro-runtime 0.8.0

设计取舍

前七部分按代码讲机制,每一章都顺带碰到一些「这样做换来了什么、付出了什么」。这一部分只有一页,把它们收到一起:每一条先说 tenferro 0.8.0 选了什么,再说收益和代价,数字取自本卷某一页的实验或本页重跑的实验,链接指向讲机制的那一页。对照的对象是 burn 0.22.1 和 candle 0.11.0。本页自己补了三组实验:同一台机器上三个库在 CPU 上的 1024² 矩阵乘和一个 256×256 的小梯度;traced 求导和编译随程序变长的代价;在 0.7.1 上重跑一次已经删掉的 WebGPU 矩阵乘,看 macOS 上丢掉的是什么。

  1. 设计取舍:十条取舍、一节正确性与文档、一节同机实测。只有列主序,和 faer、LAPACK 同布局,代价是行主序数据静默算错;没有门面 crate,native / blas 和 cuda 仍然不可加;调用方持有的 engine 让小运算不再被线程宽度拖累,代价是宽度和超订都归调用方,本机 12 线程比 8 线程慢一倍;四种张量 API 共用一套语义求导规则,新的激活和归一化靠分解求导,bug 也一起共用;运算族在核心之外,漏注册是运行期错误;运行期形状的程序每次 prepare 都重新降级,梯度图的编译仍是立方级;CPU 栈建在六个单独发布的库上,单线程大矩阵乘和 candle、burn 打平,代价是整串齐步升级;只留一条 CUDA 路径,macOS 上不再有 GPU 后端,而被删的 Metal 矩阵乘本来就比 CPU 慢 3 倍。小梯度上 tenferro 比 candle 慢 3 倍多,原因从 0.7.1 的线程进出变成了 eager 每步的簿记。
flowchart TB
  direct["直接计算主线"] --> t1["只有列主序"]
  direct --> t3["调用方持有 engine"]
  direct --> t8["单独发布的库"]
  traced["traced 主线"] --> t7["运行期形状程序"]
  traced --> t5["一套语义规则"]
  eager["eager 主线"] --> t5
  t5 --> t6["运算族在核心外"]
  t3 --> cmp["对照 candle burn"]
  t8 --> cmp
  t5 --> cmp
  t8 --> t9["只留 CUDA"]

💬 关联讨论

发起讨论
加载中...