Если вам доводилось бороться с буксующей системой (или если вы сами бывали в таком состоянии), то, возможно, вам будет интересно, какой выход из подобной ситуации предлагает компьютерная наука. В 1960 году в своей знаковой работе по теме Деннинг отметил, что болезнь легче предупредить, чем лечить. Самый простой способ профилактики – увеличение памяти: например, достаточное количество ОЗУ поможет уместить в памяти сразу все рабочие наборы запущенных программ и сократить время, необходимое на переключение контекстов. Но такие превентивные меры не помогут вам, если вы уже начали буксовать. Более того, когда речь заходит о человеческом внимании, мы явно можем использовать только то, что у нас есть, и не более.
Другой способ предотвратить пробуксовку до ее наступления – научиться говорить «нет». В частности, Деннинг агитировал за то, что система должна попросту отказывать в добавлении новой задачи, если ей не хватает памяти, чтобы разместить очередной рабочий набор. Эти меры способны предотвратить пробуксовку машин, и это разумный совет для всех угощаемых, чья тарелка уже полна. Но вместе с тем такой подход может показаться непозволительной роскошью для тех из нас, кто чувствует себя уже перегруженным – или неспособным сдерживать все, что на него валится.
В таких случаях, очевидно, нет возможности работать усердней, но вы всегда можете работать… хуже. Помимо памяти, одним из самых больших источников метаработы при контекстном переключении служит само действие выбора дальнейших действий. Временами эти действия тоже утягивают компьютер в трясину метаработы.
Если наш почтовый ящик заполнен n входящими сообщениями, то, как мы помним из теории сортировки, многократный просмотр писем с целью обнаружить самое важное из них, требующее немедленного ответа, потребует от нас выполнения O(n2) операций – n просмотров n писем. Это значит, что, обнаружив утром в почтовом ящике в три раза больше писем, чем обычно, вы потратите в девять раз больше времени на работу с ним. Более того, просматривая почту, вы поневоле подкачиваете каждое сообщение в свой мозг, одно за другим, прежде чем ответите хоть на одно из них: стопроцентный способ заставить ваш разум буксовать.
В таком состоянии вы не можете двигаться дальше, поэтому даже выполнять задачи в неверном порядке лучше, чем не делать ничего. Вместо того чтобы отвечать на самые важные сообщения в первую очередь (что требует оценки масштаба ситуации, которая займет у вас больше времени, чем сам ответ), возможно, вам стоит сделать шаг в сторону, минуя зыбь квадратичного времени, и отвечать на письма в произвольном порядке или в том, в котором они появляются на вашем экране. Размышляя в том же ключе, рабочая группа Linux несколько лет назад заменила свой диспетчер новым, который хоть и не был так силен в вычислении очередности процессов, но сполна компенсировал это скоростью вычисления. Если для вас все еще важно сохранить приоритеты, есть и другие, гораздо более интересные сделки, на которые вы можете пойти, чтобы вернуть себе продуктивность.
Объединение прерываний
Планирование в условиях реального времени – сложный и любопытный процесс отчасти благодаря взаимодействию двух не вполне совместимых показателей. Это способность к реагированию (как быстро вы можете откликаться на запросы) и производительность (как много вы можете сделать в общей сложности). Любой работавший в офисной среде способен быстро оценить напряженность между этими двумя критериями. Отчасти по этой причине существуют сотрудники, чья работа заключается в том, чтобы отвечать на звонки: они быстро реагируют, чтобы у других была возможность проявить свою производительность. Но все усложняется, когда вам, как компьютеру, приходится постоянно разрываться между быстрым реагированием и высокой производительностью. И лучший способ разобраться с делами, как бы парадоксально это ни звучало, – притормозить.
Диспетчеры операционных систем обычно определяют период, в течение которого каждая программа гарантированно работает, хотя бы немного. При этом система отдает сегмент такого периода каждой из программ. Чем больше программ запущено, тем меньше становятся сегменты и тем чаще в течение каждого периода происходят контекстные переключения. Таким образом, способность быстро реагировать поддерживается за счет продуктивности. Если оставить без присмотра этот порядок, гарантирующий каждому процессу хоть немного внимания в каждом периоде, случится катастрофа. При избыточном количестве запущенных программ сегмент для задачи сократится до такого размера, что системе придется его полностью потратить на контекстное переключение прежде, чем опять немедленно переключиться на новое задание.
Препятствие заключается в том, что гарантировать быстрое реагирование сложно. Современные операционные системы устанавливают минимальный размер для своих сегментов, который не подлежит дальнейшему делению. (В Linux, например, такой минимальный рабочий сегмент составляет около трех четвертых миллисекунды, но у людей он, скорее всего, будет составлять не менее нескольких минут.) Если после этого процессы продолжают добавляться, то период просто будет продлен. Это значит, что процессам придется ждать своей очереди дольше, чем настанет их очередь, но зато, когда она подойдет, у них будет достаточно времени, чтобы сделать что-то полезное. Установка минимального времени, которое можно потратить на одно любое задание, помогает полностью предотвратить стремление к быстрому реагированию за счет продуктивности: если минимальный сегмент больше времени, которое требуется на контекстное переключение, система никогда не сможет впасть в состояние, когда переключение будет ее единственной работой. Этот принцип также можно с легкостью перевести и в плоскость умственной деятельности человека. Метод тайм-боксинга или техника помидора, где вы устанавливаете кухонный таймер и выполняете только одно задание, пока не прозвучит сигнал, – прямое воплощение этой идеи.
Но какой величины должен быть ваш кусочек? Ответ на вопрос, сколько времени можно выделить на интервал между выполнением повторяющегося задания (например, между проверками почты), с точки зрения продуктивности крайне прост: столько, сколько возможно. Но это еще не конец; бóльшая производительность также означает более медленное реагирование.
Для вашего компьютера такая раздражающая помеха, на которую ему приходится постоянно отвлекаться, – вовсе не проверка почты. Это вы. Вы можете не шевелить мышкой несколько минут или часов, но, дотронувшись до нее, вы ожидаете немедленно увидеть движение курсора на экране, и это означает, что машина тратит огромные усилия на то, чтобы следить за вами. Чем чаще она проверяет мышку и клавиатуру, тем быстрее сможет отреагировать на запрос, но тем больше контекстных переключений ей придется совершить. Поэтому правило, которому следуют операционные системы, чтобы определить время, которое они могут выделить на решение какой-либо задачи, элементарно: столько, сколько возможно без паники или отставания от пользователя.
Когда люди ненадолго выбегают из дома по срочному делу, они обычно говорят что-то вроде «ты даже не успеешь заметить, что меня нет». Когда наши машины переключаются на вычислительные операции, им тоже приходится торопиться, чтобы мы этого не заметили. Чтобы найти этот баланс, программисты операционных систем обратились к психологии. Они штудировали работы по психофизике, чтобы найти точное количество миллисекунд простоя, нужное человеческому мозгу, чтобы зафиксировать вспышку на экране или отставание курсора. Обращать внимание на пользователя чаще нет смысла.