Ремонт принтеров, сканнеров, факсов и остальной офисной техники


назад Оглавление вперед




[90]

Главная проблема, стоящая за сложностями состояния, идентичности и изменения, состоит в том, что, введя присваивание, мы вынуждены внести в свои вычислительные модели понятие времени (time). До того, как появилось присваивание, наши программы от времени не зависели - в том смысле, что всякое выражение, обладающее значением, всегда имело одно и то же значение. Вспомним, однако, пример со снятием денег со счета и просмотром получившегося баланса из начала раздела 3.1.1:

(withdraw 25)

75

(withdraw 25) 50

Здесь последовательное вычисление одного и того же выражения приводит к различным результатам. Такое поведение возникает из-за того, что выполнение предложений присваивания (в данном случае присваивания переменной balance) отмечает моменты времени (moments in time), когда значения меняются. Результат вычисления выражения зависит не только от самого выражения, но и от того, происходит ли вычисление до или после таких моментов. Построение моделей в терминах вычислительных объектов с внутренним состоянием заставляет нас рассматривать время как существенное для программирования понятие.

Можно пойти еще дальше в структурировании наших вычислительных объектов, чтобы точнее отразить наше восприятие физического мира. Объекты мира изменяются не последовательно один за другим. Мы воспринимаем их как действующие параллельно (concurrently) - все вместе. Так что зачастую бывает естественно моделировать системы как сообщества вычислительных процессов, работающих параллельно. Точно так же, как можно сделать программы модульными, организуя их в виде объектов с раздельным внутренним состоянием, часто имеет смысл разделять вычислительные модели на части, вычисляющиеся раздельно и одновременно. Даже если на самом деле предполагается выполнять программы на последовательном компьютере, практика написания программ так, как будто вычисление будет параллельным, заставляет программиста избегать несущественных временный ограничений, и таким образом повышает модульность программ.

Параллельное вычисление не только делает программы модульнее, оно к тому же может дать выигрыш в скорости перед последовательным. Последовательные компьютеры выполняют только одну операцию за раз, так что время, необходимое для решения задачи, пропорционально общему количеству выполняемых операций.34 Однако если возможно разбить задачу на части, которые относительно независимы друг от друга и должны общаться между собой редко, может оказаться возможным раздать эти куски отдельным вычисляющим процессорам и получить выигрыш, пропорциональный числу имеющихся процессоров.

К несчастью, проблемы, связанные с присваиванием, становятся только тяжелее в присутствии параллелизма. Связано ли это с тем, что параллельно

34 На самом деле большинство процессоров выполняют несколько операций за раз, используя стратегию, называемую конвейеризация (pipelining). Хотя этот метод значительно повышает степень использования аппаратных ресурсов, он используется только для ускорения выполнения последовательного потока вычислений, сохраняя поведение последовательной программы.


работает мир, или компьютер, но явление одновременных вычислений привносит дополнительную сложность в наше понимание времени.

3.4.1 Природа времени в параллельных системах

На первый взгляд, время - вещь простая. Это порядок, накладываемый на события.35 Для всяких двух событий A и B, либо A случается раньше B, либо A и B происходят одновременно, либо A случается позже B. Например, возвращаясь к примеру с банковским счетом, пусть Петр берет с общего счета 10 долларов, а Павел 25, притом, что сначала на счету 100 долларов. На счету останется 65 долларов. В зависимости от порядка двух событий, последовательность балансов на счету будет либо $100 - $90 - $65, либо $100 - $75 - $65. В компьютерной реализации банковской системы эта изменяющаяся последовательность балансов может моделироваться через последовательные присваивания переменной balance.

Однако в некоторых ситуациях такой взгляд может вести к проблемам. Допустим, что Петр и Павел, и еще другие люди помимо них, имеют доступ к совместному банковскому счету через сеть банкоматов, разбросанных по всему миру. Последовательность значений баланса будет критическим образом зависеть от точной хронологии доступа и деталей коммуникации между машинами.

Неопределенность порядка событий может приводить к серьезным проблемам в проектировании компьютерных систем. Например, предположим, что действия Петра и Павла реализованы как два отдельных процесса с общей переменной balance, и что каждый процесс определяется процедурой из раздела 3.1.1:

(define (withdraw amount) (if (>= balance amount)

(begin (set! balance (- balance amount))

balance) "Недостаточно денег на счете"))

Если два процесса работают одновременно, то Петр может проверить баланс и попытаться снять разрешенную сумму. Однако за промежуток времени между моментами, когда Петр проверяет баланс, и когда он завершает снятие денег, Павел может снять какую-то сумму и сделать результат Петровой проверки несостоятельным.

И это еще не самое худшее. Рассмотрим выражение (set! balance (- balance amount))

которое выполняется во время каждого снятия денег. Выполнение происходит в три шага: (1) считывание значения переменной balance; (2) вычисление нового значения баланса; (3) присвоение переменной balance этого нового значения. Если процессы Петра и Павла выполняют это предложение параллельно, то в двух процессах снятия денег порядок чтения переменной balance и присваивания могут чередоваться.

Временная диаграмма на рисунке 3.29 показывает порядок событий, при котором balance сначала равен 100. Петр берет 10, Павел берет 25, и однако в итоге balance оказывается равен 75. Как показано на диаграмме, причина аномалии состоит в том, что у Павла присваивание переменной значения

35Граффити на одной стене в Кембридже: «Время - это устройство для того, чтобы случалось не все сразу».


Петр

Банк

-$ню)-

Павел

С Считать balance: $100 ) ( Считать balance: $100 )

%

Гновое значение: 100-10=90j

( установить balance в $90)

(новое значение: 100-25=75")

/ $90 ) .

\ У ( установить balance в $75 )

$75)-

время

Рис. 3.29: Временная диаграмма, показывающая, как чередование действий при двух операциях со счетом может привести к неправильному балансу.

75 основано на предположении, что значение balance, которое надо уменьшить, равно 100. Однако это предположение стало неверным, когда Петр сделал balance равным 90. Для банковской системы это катастрофическая ошибка, поскольку не сохраняется общее количество денег в системе. До транзакций общая сумма была 100 долларов. После же у Петра оказывается 10 долларов, у Павла - 25, и у банка 75.36

Общее явление, иллюстрируемое здесь, состоит в том, что различные процессы могут разделять одну и ту же переменную состояния. Сложность возникает оттого, что с этой переменной в одно и то же время может пытаться работать более одного процесса. В примере с банковским счетом во время каждой транзакции клиент должен иметь возможность действовать так, как будто остальных клиентов не существует. Когда клиент изменяет баланс, исходя из его предыдущего значения, ему надо обеспечить гарантии того, что прямо перед моментом изменения баланс все еще соответствует его, клиента, представлениям.

36Еще худшая ошибка могла бы случиться, если бы две операции set! попытались одновременно изменить баланс. В результате содержимое памяти могло бы стать случайной комбинацией данных, записанных двумя процессами. В большинство компьютеров встроена блокировка элементарных операций записи в память, которая предохраняет от такого одновременного доступа. Однако даже такой, казалось бы, простой метод защиты придает дополнительную сложность проектированию многопроцессорных компьютеров, где требуются сложные протоколы согласованности кэша (cache coherence), чтобы у разных процессоров были непротиворечивые точки зрения на содержимое памяти, при том, что данные могут дублироваться («кэшироваться») в разных процессорах, чтобы увеличить скорость доступа к памяти.



[стр.Начало] [стр.1] [стр.2] [стр.3] [стр.4] [стр.5] [стр.6] [стр.7] [стр.8] [стр.9] [стр.10] [стр.11] [стр.12] [стр.13] [стр.14] [стр.15] [стр.16] [стр.17] [стр.18] [стр.19] [стр.20] [стр.21] [стр.22] [стр.23] [стр.24] [стр.25] [стр.26] [стр.27] [стр.28] [стр.29] [стр.30] [стр.31] [стр.32] [стр.33] [стр.34] [стр.35] [стр.36] [стр.37] [стр.38] [стр.39] [стр.40] [стр.41] [стр.42] [стр.43] [стр.44] [стр.45] [стр.46] [стр.47] [стр.48] [стр.49] [стр.50] [стр.51] [стр.52] [стр.53] [стр.54] [стр.55] [стр.56] [стр.57] [стр.58] [стр.59] [стр.60] [стр.61] [стр.62] [стр.63] [стр.64] [стр.65] [стр.66] [стр.67] [стр.68] [стр.69] [стр.70] [стр.71] [стр.72] [стр.73] [стр.74] [стр.75] [стр.76] [стр.77] [стр.78] [стр.79] [стр.80] [стр.81] [стр.82] [стр.83] [стр.84] [стр.85] [стр.86] [стр.87] [стр.88] [стр.89] [стр.90] [стр.91] [стр.92] [стр.93] [стр.94] [стр.95] [стр.96] [стр.97] [стр.98] [стр.99] [стр.100] [стр.101] [стр.102] [стр.103] [стр.104] [стр.105] [стр.106] [стр.107] [стр.108] [стр.109] [стр.110] [стр.111] [стр.112] [стр.113] [стр.114] [стр.115] [стр.116] [стр.117] [стр.118] [стр.119] [стр.120] [стр.121] [стр.122] [стр.123] [стр.124] [стр.125] [стр.126] [стр.127] [стр.128] [стр.129] [стр.130] [стр.131] [стр.132] [стр.133] [стр.134] [стр.135] [стр.136] [стр.137] [стр.138] [стр.139] [стр.140] [стр.141] [стр.142] [стр.143] [стр.144] [стр.145] [стр.146] [стр.147] [стр.148] [стр.149] [стр.150] [стр.151] [стр.152] [стр.153] [стр.154] [стр.155] [стр.156] [стр.157] [стр.158] [стр.159] [стр.160] [стр.161] [стр.162] [стр.163] [стр.164] [стр.165] [стр.166] [стр.167] [стр.168] [стр.169] [стр.170] [стр.171] [стр.172] [стр.173] [стр.174] [стр.175] [стр.176] [стр.177] [стр.178] [стр.179] [стр.180] [стр.181] [стр.182] [стр.183] [стр.184] [стр.185] [стр.186] [стр.187] [стр.188] [стр.189] [стр.190] [стр.191] [стр.192] [стр.193] [стр.194] [стр.195] [стр.196]