这几天暂时解决了暑期实习的着落,便开始思考起未来。这段时间一直在思考就业方向的前途,往大里说芯片产业的路在何方,直白地说,谁将是下一个英伟达。刚刚创立行云的季宇大神在此有大量的论述,可惜我看完直接陷入混沌,只能在此流水帐地写一写。

英伟达和其他的芯片公司是很不同的。同样是从上个十年开始,受到 AI 发展对算力需求的刺激而诞生的芯片,例如谷歌的 TPU、英特尔的 Xeon Phi 等一众大厂的芯片都没有逃脱成为“某种特殊领域芯片”的命运,而英伟达却建立了生态,成为了 AI 领域的指定芯片。我想以史为鉴类比一下其他领域,可惜我还没有足够的阅历,就不再展开了。

AI 领域的生态,或者说“定义权”的争夺异常激烈。AI 算法本身的迭代暂且不说,AI 框架方面,就经历了从 tensorflow、Keras 等各个框架百家争鸣,到现在 pytorch 一统江湖的局面。网上一直有个梗图,某某技术生成打破生态壁垒,可以支持xxxx框架在xx硬件上运行,但是实际上所有人都只关心 pytorch 和 CUDA。生态的纷争中,谁能赢并不容易判断,但是需要关心的一点是,AI 领域的具体应用越是百战,需要一个统一的生态作为支柱。一旦有一个技术能够成功占据大部分市场,成为第二名就不再有意义。反之,目前的 Transformer 技术日趋收敛,各家也在逐渐地开发定制的训练和推理框架,力求榨干最后一滴性能。原本训练和推理的框架五花八门,通常需要中间表示进行衔接,因而诞生了 onnx。不过目前看来,这一层兼容层存在的意义也在日益消减了。例如,海思就直接把自家的算力对接到了 torch 的后端,即 triton,不需要经过 onnx 这一将就的中间层。

在这一场争夺中,唯一的赢家是英伟达。基于英伟达这一不变的硬件平台,软件生态间的分裂程度,不存在减少的时候,只有从一个环节转移到另一个环节。pytorch 前脚统一神经网络的语言层,后脚就有 triton tilelang 等等在争夺算子层的定义权,始终无法达成一致。无法达成一致时,各家的算力卡就会被软件栈的适配任务压垮,英伟达则作为大家唯一能够达成的一致,坐享市场的绝大部分利润。

不过,只要把软件生态建立起来,就能够取代英伟达吗?这实际上基本不可能。英伟达的显卡,现在又被成为通用显卡(GPGPU),能够在高性能 CPU 的封锁中突围,是有远见的。常有一道面试题问道 GPGPU 的 SIMT,和 CPU 中的 SIMD 有何区别,这是非常关键的问题:

  • SIMT 和 SIMD 最大最明显的区别是在软件上,程序员需要编写看似多线程的标量代码,这带来了一定的编程负担,但实际上这并没有增加程序员编写高性能程序的负担,而是非常好地暴露了程序的一层数据并行性,提供了大量的优化机会。
  • 硬件上,SIMT 实际上会以 32 个为一 warp 运行,共享同一个控制流,这对应了 SIMD 的单指令多数据,并无太大区别。但关键点在于,SIMT 执行时会将多个 warp 同时以超线程的形式执行,是为多线程;反之,CPU 中虽然有乱序执行等技术,但乱序执行的前提是程序中已经提供了多组并行的数据流,对于高度线性依赖的数据流无能为力。
  • 超线程技术是 SIMT 的立身之本,通过同时执行多个 warp(据说推荐超过 6 个),GPGPU 可以几乎无视数据依赖导致的流水编排的难度,只靠最简单的写法就达到了大部分的性能。这样做的结果是 SIMT 的吞吐量远远高于 SIMD,而代价是延迟增加。

英伟达打败 CPU 的关键是抓住了 CPU 的根基:延迟。延迟可以说是 CPU 性能的最关键指标,任何的多核、并行、吞吐量的取舍,都需要让步于延迟,也就是单核性能。因此,CPU 只可能在现有的条件下增删运算单元,而不可能采用大规模并行的方法。实际上,超线程的能力在目前的 CPU 上反而在逐渐消失,理由是资源不足以支撑两个同类的线程,而 CPU 运行两个异类线程时通常负载不高。

而超线程的本意,多个线程交替利用硬件资源,实际上就是抓住了高性能软件编写的痛点:各个硬件资源间的依赖关系太过复杂,无法依靠软件静态调度便达到理想的水平。SIMT 中,资源调度的任务被尽可能交给了动态的线程调度器,可以利用更多的信息,取得更好的结果也可以理解。当然,当性能提高到接近极限时,任何的架构都需要专家编写高性能算子,在这里需要强调的是 SIMT 带来了极致的学习曲线,只需要写出程序就能利用大部分资源,而通常的单线程的程序需要大量的努力才能达到基本可用的级别。

如果没有找到 SIMT 的痛点,做出让 GPGPU 无法接收的取舍,实际上就不可能成功。例如之前很多 DSA 都通过增加矩阵乘法单元取得了超越英伟达的成绩,但结果是 Tensor Core 加入英伟达显卡,成为算力指标的核心硬件。而且,利用特化的硬件时,最本质的问题是如何让所有人都利用上,尤其是不同的应用和不同的硬件间如何建立映射,总不能说这个芯片是跑 MobileNet ,那个跑 ResNet 吧。

先碎碎念这么多,有空再整理成文。