构建灵活软件系统的有效方法就是通过嵌入式脚本语言使软件系统具有扩展性。TCL、Python 以及 Lua 等语言让程序员能够对许多软件 系统的行为进行安排和定制 – 例如,游戏大多由 C++ 编写,但通常会用 Lua 来实现人物及其他游戏机制的 AI(人工智能),并用 Python 代码通过协调 C++ 或 Fortran 库代码的执行来编写高性能计算应用程序。
大多数嵌入式脚本语言都属于解释型语言,因此不适合用来实现性能关键的内部循环。此外,在许多注重性能的领域,通过核心系统与嵌入式语言之间的接口进行传递所带来的运行时开销多得难以接受,尤其是当需要进行频繁的转换时更是如此。因此,大多数以性能为导向的系统并没有在性能关键部分的核心领域提供可编程性的选项。
然而,在图形领域,可编程的 高 性 能 光 栅 化 流 水 线 在 过 去的十年里一直是交互式渲染的核心 。 现 代 图 形 处 理 单 元 ( G P U )的 程 序 员 用 H L S L 或 G L S L等 基 于 C 的 语 言 编 写 “ 着 色器”,为流水线的内部循环提供代码。着色器的编程模型是数据并行型;此模型提供了丰富的并行性,可以很好地映射到底层的SIMD 硬件体系结构。虽然除图形领域以外,其他许多领域也都在使用可编程 GPU 以实现高性能计算,但能否针对 GPU构建可编程的高性能软件系统仍是个未知数。
以下由 Parker 等人编著的这篇论文就将介绍如何在这样一种系统中让可编程性和高性能兼而有之。他们的系统 OptiX 所涉及的领域是适用于图像合成的交互式光线跟踪。光线跟踪是一种非常灵活的渲染方法,可以比光栅化更有效地模拟许多重要的照明效果,但它在交互式图形中的应用却受到了限制,直到最近 OptiX 的出现,而在此之前,在光线跟踪系统中,性能和灵活性始终无法兼得。
作者为经典的光线跟踪算法开发了一套优雅的表达式,即每个阶段都从用户提供的代码进行组装的可编程数据流图。OptiX为各个阶段之间运行的核心几何和并行任务调度算法提供了高度优化的实现。与 GPU 光栅化流水线一样,程序员可以完全控制可编程性关键点的系统行为,而无需担心高性能 GPU 编程的细节。OptiX 对用户提供的内核使用 CUDA 语言;CUDA 提供了可在 GPU 上高效运行的数据并行编程模型。
OptiX 消除了核心 OptiX 系统代码与用户代码之间的障碍,从而在保证性能的同时提供了可编程性。它对这两类代码都使用专用的 JIT 编译器,不仅允许在系统这两部分之间的边界中实现内联,而且允许常量传播和死代码消除,从而生成专用的系统版本。因此核心OptiX 系统可以提供最终可能不需要的功能;编译系统时会将此类功能的代码删除。该系统实现方法允许 OptiX用户实现 3D 场景中几何体的自定 义 表 示 方 法 和 算 法 , 以 模 拟照明和反射 – 在任何光线跟踪技术中,它们都是定制的关键领域。作者成功设计了正确的问题分解方法,这可说明用 OptiX 实现的光线跟踪应用的多样性,这些应用不仅仅包括渲染,甚至包括音频模拟和碰撞检测。所生成的系统非常接近于峰值效率,这使得 OptiX 迅速成为了大多数GPU 光线跟踪的标准基础。
在 GPU 上引进可编程光栅化流水线的一个意想不到的成功,就是程序员在使用 GPU 光栅化流水线时所表现出来的创造性,他们使用的方式是原始设计者都未曾想到的。通过将灵活并且高性能的光线跟踪带给更多的开发人员,OptiX 很可能会以今天无法预测的方式点燃创新之火。
如果您关心如何编写可扩展的高性能软件系统,那么本文是您的必读之物。虽然本文的目标=硬件体系结构是 GPU,但基本思想同样适用于 CPU 上的高性能软件系统。今天,虽然 LLVM 等高质量编译器工具包使得以这种方式实现各种系统的门槛大大降低,但潜在的优势是巨大的。