为什么是 l(k 和 q 的新运行时)

Lobsters Hottest 工具

摘要

K 和 Q 编程语言的新运行时,利用 SIMD、并行、融合和压缩技术重新构想执行方式,以更好地发挥现代硬件的性能。

<p><a href="https://lobste.rs/s/wkm8tk/why_l_new_runtime_for_k_q">评论</a></p>
查看原文
查看缓存全文

缓存时间: 2026/07/21 08:39

# Why l. | l 来源:https://lv1.sh/blog/why-l/ 我从 2001 年开始接触 K 和 Q,至今已近二十五年。首先说一个显而易见的事实:Arthur Whitney 是个天才。 K 和 Q 至今仍是非凡的语言。它们的设计精巧、紧凑、优美。但尽管经过了多年的优化、扩展和修正,核心的实现模型仍然扎根于 Arthur 在 20 世纪 90 年代的原始洞见。 我并非想要改变这门语言。我还没有狂妄到觉得自己应该发明一种新语言。我想做的是,针对我们今天实际使用的机器,重新构想其实现。 2026 年的计算机已经不是 1997 年的计算机了。CPU 更宽。内存相对更慢。每台机器都有多个核心。许多机器还配有 GPU、NPU、AMX 单元、NEON、AVX、VNNI 以及其他专用执行引擎。硬件已经发生了巨大的变化,而编程模型却没有跟上。 l 是我试图在保留语言(K、Q、qSQL、IPC,以及整个现有代码世界)的同时,重构底层执行引擎的一次尝试。该实现围绕四个核心理念构建:**SIMD、并行性、融合和压缩**。 ## SIMD 作为一等原始操作 我希望每个运算符都能自动利用硬件优势。在考虑集群、GPU 或分布式系统之前,一个更简单的问题是:每个原始操作在单核上能有多快? 这意味着让每一个时钟周期都物尽其用。这意味着将 SIMD 视为原始操作执行的默认路径,而非可选的优化手段。如果硬件每条指令能处理多个值,语言就应该自动利用这一点,无需重写代码,无需向量内建函数,也无需用户思考。原始操作就应该是快速的。 ## 默认并行 并行性对于数组语言来说一直是自然而然的事情。APL、K 和 Q 都将工作表达为对数组进行的大规模、规则操作,而这正是现代 CPU 能够利用的结构。 但我希望从头开始思考这个问题。l 将并行执行视为原始运行时的一部分,而非将它作为外部工具拼接过来。小数组走快速单核 SIMD 路径。更大的数组自动在多个工作线程间拆分。用户从不需要决定何时并行化;运行时根据操作的大小、形状和成本来决定。 当数组变得更大时,同样的思路会扩展到加速器上。在一台现代 Apple 机器上,许多工作负载太小,不值得将数据移交给 GPU,但有些则不是。小值留在 CPU 流水线上。较大的值使用线程。最大的操作在划算时移交给 GPU、NPU 或其他后端。你不应该因为硬件变化就需要使用不同版本的语言。 ## 透明融合 当我在金融服务中使用 K 和 Q 时,代码通常很优雅。当它变慢时,原因很少是原始操作本身,而是中间结果的分配。 你写了一些漂亮的代码: `` q) sum sqrt x `` 概念上很简单:对每个值取平方根,然后求和。但传统的实现可能会为 `sqrt x` 分配一整个中间向量,紧接着在 `sum` 中把它消耗掉。这种分配就是浪费。 l 使融合变得透明。运行时会链式组合原始操作,并尽可能消除中间对象。在 `sum sqrt x` 中,求和循环直接消费取平方根后的值。在安全的情况下,它会原地修改临时变量。在可能的情况下,它会将整个表达式压缩成一个流水线。你仍然写普通的 K 或 Q 代码。实现让显而易见的事变得快速。 ## 压缩作为运行时概念 第四个理念,也是最困难、或许也是最重要的,是压缩。它不应该是一个放在旁边的存储功能,它应该是运行时内部的一等概念。 一个运算符不应该关心它操作的对象是否被压缩。运行时应该知道如何直接操作压缩数据。为了让压缩、SIMD、线程化和融合能够正确组合,它们必须被一起设计。这是核心的实现挑战。 除了少数例外,大多数原始操作可以直接处理压缩数据。一个巨大的向量可以保持压缩状态,在内存中移动更少的字节,更好地适应缓存,并且仍然产生相同的结果。 > 内存带宽是敌人。现代 CPU 非常快。瓶颈很少是算术计算,而是数据移动:从 RAM 到缓存,从缓存到寄存器,从核心到核心,从 CPU 到加速器。 让软件变快的最简单方法是,在更短的距离内移动更少的数据。这就是为什么压缩对 l 如此重要。如果一个向量能用更少的字节表示,l 就会保持这种状态。如果数据能留在缓存中,它就留在缓存中。如果一个操作可以在不解压完整向量的情况下执行,它就这样做。运行时只移动计算正确答案所需的最少字节数。 ## 护栏:完全兼容 K 和 Q 所有这些的护栏是兼容性。我希望 l 就是 K 和 Q,而不是“受 K 启发”,不是“类似 Q”。我希望现有的商用 k4 和 Q 代码无需修改即可运行。我不想抛弃二十多年的代码、谜题和我成长的社区。 这意味着要实现这门语言、qSQL、IPC 以及周围的执行模型,并且要拿真实的代码(不仅仅是示例)来问:它能否实际在更大的系统中运行?一旦你承诺做到这一点,问题就会变得困难得多,也更有意义得多。 l 的目的不是创造一门新语言然后让人们迁移。目的是保留语言,并替换底层的机器。**相同的语言。全新的引擎。** K 和 Q 给了我们有史以来构建过的最强大的数组编程模型之一。l 要问的是,当实现从头开始为现代硬件设计时(默认采用 SIMD,默认并行,默认融合,默认压缩),这个模型会是什么样子。 这就是我构建 l 的原因。

相似文章

l: 用于 k 和 q 的新运行时

Hacker News Top

l 是一个用于 k4、q 和 qSQL 的新运行时,提供透明的 SIMD、压缩向量和自动并行性,同时保持与现有代码的完全兼容。它针对华尔街的高性能计算。

QBE – 编译器后端

Hacker News Top

QBE 是一个紧凑的、爱好级别的编译器后端,仅用 10% 的代码即可实现工业级优化编译器 70% 的性能,支持 amd64、arm64 和 riscv64,并采用简单的基于 SSA 的中间语言。