技术长草。
今天讲到 Kahn Process Network(KPN),我看到图示之后立刻反应过来,这结构不就是消息队列(message queue)吗。噫,消息队列“天然地”支持分布式架构,我理所当然地就接受了,因为有一点工程经验它就显得很自然了。没想到也是有一个理论支持的。
讲到并行化的实现思路(也即 parallelism),一般分为两类。多线程实现的“并行”,虽然在具体实现中是不可或缺的,但是只能说是技巧(technique),而不是架构(architecture)。这门课针对的是 parallelism by design,是架构上的并行,而且在系统设计时就有着确定的行为。(注:KPN 中各个过程是可以并行的,但是整个系统仍然有着确定的行为。这是 KPN 的一个特性。)在课程描述里还讲到有一个叫做 parallelism by compilation 的,我不知道是什么(毕竟 compilation 可能指常见的“编译”之外的更泛的意思),所以就去问了。教授(略有学究气的老先生)回答说,如果编译器足够智能的话,就可以将过程分离(注:原话用的是“process”,不过并不是指进程,而是抽象出的过程——粒度可以是大到功能模块,也可以小到一个原子操作),并抽取出可以并行的部分,自动并行。说完之后,他盯着我,很认真地(从语气和眼神里可以体会到)说:“我坚信确定的并行化(parallelism by design)是最好的方案,虽然很少人这么想。”我不知道该说什么好了。我大概能猜到他的心情;不过总有一种“力挽狂澜”之感,专门开这么一门课。
这又让我想起了复杂系统的设计方式,构造和自组织。我的思想仍然受到这篇文章的影响。或许以前我引用过,但是在这里我还是想引用一次:
但我并不认为 Java 有很大的机会,因为它本质上是为构造大型复杂系统而设计的。什么是大型复杂系统?就是由人清清楚楚描述和构造出来的系统,其规模和复杂性是外生的,或者说外界赋予的。
而 AI 的本质是一个自学习、自组织的系统,其规模和复杂性是一个数学模型在数据的喂养下自己长出来的,是内生的。
不过,我仍然认为关键系统需要人为地设计其架构。“it just works”地在精细尺度上的、不可预测的并行,虽然显得很迷人,却是非常危险的。
想起编译器优化的同时我又想起了之前和“博导”(我以前的一个同学,高中去了美国,大学读的……好像是电子工程;反正一直碾压同龄人)的一段对话。以下是节选:
(前略)
我:这算什么,原教旨?(注:指纯 C 写移动设备 app)
博导:算是吧,C 系手动内存正统,Java 等 GC 语言异端!我要确定性,掌控每一行代码!
我:抱歉,指令预测真的可以为所欲为。除非不断加 memory barrier,要不严格来说你无法掌控“每一行代码”。
博导:我知道 Intel 内部运作,知道 reordering 和 uop,所以是掌控的。(注:uop = micro-operation)
博导:当然更加知道 GCC 每一行代码会编译成什么。
我:(图片:熊猫膜拜)
博导:其实 Intel 8卷读一遍就知道了。
我:(图片:许多熊猫一起膜拜)
不知道放哪里好,就放这里吧。
原文:
In a sense, the specular term gets “dibs” on the incoming light energy, and the diffuse term
can only use its “leftovers”.
译文:
某种意义上,specular项指着入射光能量大喊“归我了”,然后diffuse项只能用“剩下的”。
我读到这里的时候哈哈大笑。虽然这个翻译仍然有可以提高的地方,但是这个版本很有画面感。
某种意义上,高光(specular)项占了入射光能量的大头,散射(diffuse)项就只能利用余下的能量。