灯下 登录
计算机科学 / SICP / section 中英对照

3.4 Concurrency: Time Is of the Essence

We’ve seen the power of computational objects with local state as tools for

modeling. Yet, as 3.1.3 warned, this power extracts a price: the

loss of referential transparency, giving rise to a thicket of questions about

sameness and change, and the need to abandon the substitution model of

evaluation in favor of the more intricate environment model.

我们已经看到,具有局部状态的计算对象是建模的有力工具。然而,正如 3.1.3 节所警示的,这种能力是有代价的:引用透明性的丧失,由此引发了一系列关于同一性与变化的疑问,以及放弃代换模型转而采用更为复杂的环境模型的必要。

The central issue lurking beneath the complexity of state, sameness, and change

is that by introducing assignment we are forced to admit

time into

our computational models. Before we introduced assignment, all our programs

were timeless, in the sense that any expression that has a value always has the

same value. In contrast, recall the example of modeling withdrawals from a

bank account and returning the resulting balance, introduced at the beginning

of 3.1.1:

潜伏在状态、同一性与变化这一复杂性之下的核心问题在于:引入赋值迫使我们将时间 (time) 纳入计算模型之中。在引入赋值之前,我们的所有程序都是无时间性的,即任何具有某个值的表达式始终具有相同的值。与此相对,回忆一下 3.1.1 节开头引入的对银行账户进行取款并返回余额的建模示例:

Here successive evaluations of the same expression yield different values.

This behavior arises from the fact that the execution of assignment statements

(in this case, assignments to the variable balance) delineates

在这里,对同一表达式的连续求值会产生不同的值。这种行为源于赋值语句的执行(在这里,是对变量 balance 的赋值)划定了

moments in time when values change. The result of evaluating an

expression depends not only on the expression itself, but also on whether the

evaluation occurs before or after these moments. Building models in terms of

computational objects with local state forces us to confront time as an

essential concept in programming.

值发生变化的时间节点。对一个表达式求值的结果,不仅取决于表达式本身,还取决于这次求值发生在这些节点之前还是之后。用具有局部状态的计算对象来构建模型,迫使我们将时间作为程序设计中的一个本质概念来正视。

We can go further in structuring computational models to match our perception

of the physical world. Objects in the world do not change one at a time in

sequence. Rather we perceive them as acting

concurrently—all at

once. So it is often natural to model systems as collections of computational

processes that execute concurrently. Just as we can make our programs modular

by organizing models in terms of objects with separate local state, it is often

appropriate to divide computational models into parts that evolve separately

and concurrently. Even if the programs are to be executed on a sequential

computer, the practice of writing programs as if they were to be executed

concurrently forces the programmer to avoid inessential timing constraints and

thus makes programs more modular.

我们还可以在结构化计算模型方面更进一步,使其与我们对物理世界的感知相匹配。现实世界中的对象并非依次逐一地发生变化,我们感知到它们是并发地 (concurrently)——同时——发生作用的。因此,将系统建模为并发执行的计算过程的集合,往往是自然而然的。正如我们可以通过将模型组织为具有各自局部状态的对象来使程序具有模块性一样,将计算模型划分为各自独立、并发演进的部分,也常常是恰当的。即使程序最终在顺序计算机上执行,以并发方式编写程序的做法也能迫使程序员避免引入不必要的时序约束,从而使程序更具模块性。

In addition to making programs more modular, concurrent computation can provide

a speed advantage over sequential computation. Sequential computers execute

only one operation at a time, so the amount of time it takes to perform a task

is proportional to the total number of operations performed. However, if it is possible to decompose a problem

into pieces that are relatively independent and need to communicate only

rarely, it may be possible to allocate pieces to separate computing processors,

producing a speed advantage proportional to the number of processors available.

并发计算除了使程序更具模块性之外,还能相对于顺序计算提供速度上的优势。顺序计算机每次只执行一个操作,因此完成一项任务所需的时间与总操作数成正比。然而,如果能够将一个问题分解为若干相对独立、彼此之间只需偶尔通信的部分,就有可能将这些部分分配给不同的处理器,从而获得与可用处理器数量成正比的速度提升。

Unfortunately, the complexities introduced by assignment become even more

problematic in the presence of concurrency. The fact of concurrent execution,

either because the world operates in parallel or because our computers do,

entails additional complexity in our understanding of time.

遗憾的是,赋值所引入的复杂性在并发存在时变得更加棘手。并发执行这一事实——无论是因为现实世界本身是并行运作的,还是因为我们的计算机是并行的——都给我们对时间的理解带来了额外的复杂性。

Racket #lang sicp
(withdraw 25)
75

(withdraw 25)
50