并发与并行:在计算边界上起舞

并发与并行是两个时常被并置、也常常被混用的概念。自 2010 年代的多核时代以来,算法设计和架构考量早已越出单线程经典范畴;基础算法领域的经典著作《算法导论》也在更新中加入了对并行算法的讨论,不过仍有声音认为,其篇幅和深度远未充分。

按照我个人更愿意采信的定义,并发指的是同时启动多个任务;并行指的是同时执行多个任务。由于 CPU 调度的基本单位是内核线程(或轻量级进程),单纯以进程作为衡量尺度,并不是一个足够精确的区分标准;这也使得多进程与多线程在环境独立性和运行开销之外,在应用层的体感上往往高度相似。

并发一直是实战中极其棘手的区域。那些不知何时发生的中断与调度,很容易催生形态诡异的竞态条件;对象生命周期也随之变得暧昧,仿佛全靠程序员脆弱的心智模型和团队约定勉力维系。尤其当高权限的内核进程来回穿梭时,整个画面就会呈现出一种近乎残酷的美妙。

并行化则是时代的大趋势。从 OpenMP、pthreads 到后来的 CUDA,其背后其实是对计算能力的一次重新诠释:传统 RAM 模型搭配渐进复杂度分析,固然有效指导了过去数十年的算法设计,但在多核时代终究显出不足,于是 PRAM、LogP 等模型应运而生。这些形式化方法对现实工程问题大有裨益,因为它们描述着能力的边界,以及使用这些能力的框架。

当然,若继续追问这种计算能力的源泉,答案终究还是硬件进步。多核并行化不同于指令级并行、超标量或向量化;它更多由超线程、推拉迁移与亲和性、对称或异构多处理等机制共同绘就其波澜壮阔的底色。这些内容在优化层面尤其值得关注,因为它们并不只是背景知识,而是性能边界本身。

即使到了 AI 打开一片新天地的今天,分布式、系统编程、高性能计算依旧是压在头顶的三座大山。若允许一点个人色彩和哲学意味:这些领域本就是计算机在“计算之近似”的边界上跳舞,形式化方法与现实系统之间的张力,在这里显露得淋漓尽致。