Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Падающий снег в скриптах с контролем нагрузки.


краткое содержание

Падающий снег в скриптах с контролем нагрузки.

Прорабатывается метод определения и регулирования процента загруженности процессора выполняющимся скриптом с анимацией. Скрипт падающего снега.
Существует дней: 236
Автор: 12345c
Другие выпуски:
Рассылка 'Упражнения по яванскому письму. Javascript.'
 
Статья.
12.12.06

Анимация объёмных вычислений в скрипте в реальном времени.

Задача вытекает из необходимости подстраивать объём вычислений в некоторых скриптах в зависимости от мощности процессора и реальной измеряемой нагрузки на клиентский компьютер.

Пришло время, когда снова вспомнили о снеге. Процент поиска скрипта снега и количество его скачиваний резко возросло, и поднялись смежные задачи, задуманные в отношении него год назад. В выпуске рассылки http://javascript.aho.ru/subs/subs002.shtml был упомянут скрипт падающего снега, рассказано о том, что он сделан на базе скрипта с наиболее удачным и естественным поведением снежинок и доработан до совместимости с современными браузерами. Версий браузеров стало больше, добавились номера и возможности версий всех основных браузеров, что отразилось в несколько доработанном коде. Но самое главное впереди.

На скрипт жаловались о том, что он сильно нагружает процессор, если задать много снежинок, хотя выглядит эффектно. Стоит открыть 3 окна со скриптом, как анимация начинает тормозить. А куда деваться? Больше снега - больше нагрузки, меньше снега - меньше эффектности. И была задумана задача сделать количество снежинок подстраивающимся под мощность процессора и системы. Как? Все ведь знают, что браузер не получает информации о загруженности процессора клиента. Присмотревшись к задаче этой, и к другим задачам подобного класса (с по возможности большой нагрузкой), замечаешь, что решение возможно - если скрипт замедлился, он может измерить, насколько. И понимаешь, насколько полезным был бы метод решения для подобных задач. Это пласт абстракции, которую нужно освоить. Снежинки - это всего лишь предмет для отработки метода измерения гораздо более важных дележей времени, происходящих в глубинах планировщика процессов операционной системы. Если получится один, значит, получатся и подобные.

 

Вначале замечания не для философов. Читающие эти строки дизайнеры и программисты никогда в большинстве своём не программировали игр (как и автор). Для программиста по играм изложенная ниже философия вывода анимации покажется азбучной и примитивной. Для всех остальных она будет необходима, потому что задача, за которую мы берёмся и которую в данном выпуске только рассматриваем - нетривиальна для скриптов. В ней, в анимации, есть свой подход и философия, которой надо проникнуться и осознать, прежде чем начать делать программу руками. Нужно знать, почему автор решил ввести столь несложные, но малопонятные процедуры, а, так как они пронизаны философией и упрощены до предела, одни комментарии никогда не заменят введения - данной статьи, разворачивающей порядок постановки задач в их естественном течении. Только прочитавшие и постигшие философию анимации (шутка) и прошедшие через ряд уловок для реализации её в скриптах (уже не шутка), смогут смотреть на будущую программу не как на животное, движимое чудом вдохновения, а как на живой организм, каждый орган которого живёт по-научному. Который можно заставить работать в других условиях или хотя бы знать, ради чего он сделан.

Без философии просмотр скрипта будет подобен походу учителя в зоопарк со словами: "Смотрите, дети, это слон!", без физики движения его ног и биологии существования. Читатель, на которого свалится скрипт, будет раздавлен его массой вместо того, чтобы погрузиться в его жизнь. Да и время, и тема скрипта актуальна - снег. Как много в этом звуке... Не для того мы читаем статьи по скриптам, чтобы брать их и пользоваться, а чтобы писать подобные, ведь так? Если так - читаем дальше.

 

Примеры таких скриптов - движение рисунков по экрану, анимация падающего снега или поднимающихся пузырьков воздуха. Двумерное вращение фигур. Обновление текстовых слоёв с контролем времени на сложный скриптовой рендеринг (вычисления по прорисовке) плана страницы. текстовые задачи традиционно с малым объёмом вычислений, потому что много делают встроенные средства браузера, но и там можно представить (подсветка цитат, синтаксиса, найденных слов, расстановка переносов, контроль обрезаний текста) объёмные вычисления. Если их нет сейчас, они будут послезавтра. У тех, кто не скажет, что: "Сложно это, сойдёт и так".

Это не открытие Америки. Это цепь рассуждений, которая делается каждым аниматором, построителем движка игры или прочей системы реального времени при планировании вычисления фреймов. Особенность нашего браузерного приложения в том, что способов регулировки скорости вычислений почти нет - мы можем или нормально работать при недогруженном процессоре, и тогда нет проблем, или продетектировать и измерить уровень перегрузки процессора, если она случилась. Но ни повлиять на приоритет работ в случае перегрузки, ни даже узнать, что будет перегрузка, мы не можем. Прерывание есть единственное - по таймеру, которое не сработает вовремя. Информации о проценте загрузки процессора нет вообще до тех пор, пока не извлечём её из величины запаздывания прерывания таймера.

Поэтому первый случай - когда перегрузки заведомо нет на клиенте - случай редкий для сложных эффектных анимаций. Грубо говоря, она должна нагружать средний процессор процентов на 10, памятуя о том, что есть слабые процессоры, которые будут загружаться на 50-70, и о том, что есть соседние окна, которые тоже хотят считать. Благо одно, что неактивные окна постепенно теряют приоритет вычислений, а скрытые участки окон не отрисовываются и экономят объём работ. (Они же есть некоторый минус, так как вносят неконтролируемый дисбаланс, о котором тоже можем узнать только по факту измерений перегрузки.)

Способ, которым можем измерять нагрузку, известен один - при физической загрузке поцессорного времени на 100% процессы, в том числе и скрипты в окнах, начинают притормаживать. Обнаруживается различие между планируемым и реальным временем выполнения. Поэтому сможем сказать, что процессор перегружен, и насколько, только если создадим ему вначале перегрузку. Если скрипт будет работать в нормальном недогруженном режиме, он ничего не сможет сказать о реальной загрузке процессора - система с планировщиком процессов будет выделять столько времени, сколько требуется. Выходит, что нам нужна перегрузка, чтобы вычислить загруженность данным процессом. Но тут же начнут брать приоритет другие, может быть, более серьёзные процессы ОС. Которые неожиданны и подобны орде - мало в каких ОС будет в равной степени выделяться приоритет на запуск и на выполнение новой задачи. Открыли программу или окно - в процессорное время врывается опустошение, которое надо пережить.

Перегрузки обычно возникают при большом объёме анимации и сопровождаются меньшей скоростью отрисовки фреймов (как в видеообработке называются кадры, относительно которых строится экстраполяция дальнейших кадров, а в нашем случае фреймом назовём один цикл отрисовки изображения в окне браузера). Поэтому в простом случае испытания на перегрузку процессора увидим замедление работы скрипта - то самое, которого хотим избежать. Это один недостаток подхода. Второй в том, что, измеряя границу перегрузки, в дальнейшем не можем узнать, насколько далеко от неё оказались, не делая время от времени "экспериментов" на обнаружение перегрузки. Значит, притормаживания должны время от времени случаться.

 

Определив будущие проблемы, подумаем над их возможными решениями. Видятся варианты:

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

2) сделать притормаживания как можно менее видимыми, и в идеале, невидимыми. Для этого иметь чёткое представление о полезной работе и экспериментальной (с дозированной перегрузкой). Если речь идёт об анимации, то надо иметь ряд заготовленных фреймов, подсчитанных заранее, чтобы на вывод их тратить известное и дозированно меньшее время. Тогда вместо абстрактной экспериментальной загрузки выполняем действие по вычислению будущих фреймов. Получится, что успеем и измерить уровень перегрузки, и видеоряд почти не пострадает, так как вывод его будем отрабатывать не по искажающемуся таймеру, а по часам. Возможно, будет наблюдаться мелкое дрожание плавности движения из-за неточного времени начала отрисовки. Избежать такого мелкого дрожания анимации - пилотаж следующего порядка. Для этого надо предполагать (частично вычислив) уровень перегрузки и дать объём расчёта такой, чтобы к желаемому времени процесс отрисовки был на очереди. Значит, надо чётко представлять объём вычислений и уметь резать его на точно заданные части. (На которые планировщик всё равно повлияет своевольно.)

3) уменьшать объём вычислений, исходя из способности обработать фреймы, не за счёт скорости отрисовки, а за счёт качества вывода. Значит, нужен механизм регулирования объёма по заданному качеству. Фактически, нужно научиться менять или детальность фрейма, или частоту следования. Последнее означает, что учитывается не только планируемое замедление, но и длительность фрагмента вычислений. Что не так уж сложно, если будет механизм отмеривания объёма вычислений с расчётом уложиться в интервал. (Сложно - тут понятие относительное. Не забываем, что работает не машинный язык, а скрипт со скоростями операторов, сильно зависящими от реализации браузера. Да, различие браузеров будет ещё одним кошмаром, преследующим каждую нить наших процессов, задыхающихся в отработке самих себя. На один оператор смены большой картинки (.src=) пойдёт столько времени, что на спокойную отрисовку придётся на некоторое время забыть. И на сколько загружен кеш браузера, никто заранее не знает, и работает ли сейчас дисковый кеш ОС.)

4) в дальнейшем, может быть, удастся (до следующей версии браузера) дойти до 4-й степени пилотажа - делать перегрузки кратковременными и сильными, потому что только так можно узнать, где их граница. И за это время не исказить анимацию и измерить уровень. И выполнить полезные вычисления. Если бы был доступ к уровню загрузки планировщика, не было бы необходимости строить пики.

5) из способа решения задач следует, что структура алгоритма должна быть испещрена точками проверки выполнения, чтобы из любой точки прервать процесс и переключиться на отрисовку. При этом знать объём вычислений между точками. Как легко это звучит для машинного языка и как сомнительно для скрипта. В машинном или низкоуровневом для этого есть прерывания - остановились в любой момент и делаем приоритетную задачу. Даже речи нет о точках останова. В скрипте нет прерываний (кроме ...), ему надо проверять свой объём работ, он должен сам отдавать выполнение отрисовке в заданных точках.

 

Наверное, перечисление задач всё больше убеждает в том, что "Это сложно" и вообще-то не для скриптов. Тем не менее, есть простейшая мысль: "Нельзя перегружать и замедлять анимацию!", и от этого надо решение с чего-то начинать. Пусть, сделаем начало, первый пункт, но зная, куда двигаться и насколько далеко до совершенства.

Попробуем на базе конкретного скрипта выполнить, пусть приблизительно, 2-3 пункта условий регулировки нагрузки. Пусть, не очень обращая внимания на соседние процессы и уровень пилотажа. Но чтобы работало.

1) перегрузить процессор анимацией, чтобы узнать мощность системы. Придётся повторять время от времени, потому что можем попасть на случайный запуск программы в другом окне или иное действие пользователя. Абстрагироваться от колебаний загрузки, вывести достоверную среднюю мощность за 1.5-5 секунд.

2) уменьшить нагрузку так, чтобы процессор работал на 50-70% мощности. Остальное даём другим окнам ради стабильности анимации.

3) Время от времени повышать нагрузку, проверяя и корректируя представление о найденном ресурсе мощности. Пусть в эти секунды будет замедление анимации, для первого раза и этого будет достаточно. Сначала в 1.5 раза; если не привело к эффекту - то ещё.

При решении получим, что скрипт сможет работать в среднем на 70% загрузки в большом диапазоне мощностей процессоров (компьютеров), создавая небольшие перегрузки на 120-150% иногда. Качество анимации будет определяться детальностью вычислений и скоростью смены фреймов.

Для реализации возьмём скрипт падающего снега. Его детальная прорисовка движения снежинок сильно нагружает процессор средней мощности (производительность видеокарты тоже имеет значение). Будем регулировать детальность количеством снежинок, которое можно будет выпустить для показа с заданной нагрузкой. Одновременно (в случае успеха) этот скрипт станет интегрированным тестом мощности системы - число снежинок для заданных рисунка снежинки и его размеров.

 

Уровень: для философов

Примечание.
12.12.06

Где же пример?

Он в работе.

Вряд ли имеет смысл выкладывать промежуточный вариант сейчас, никто не возьмётся работать с ним дальше. А результат, как показывают тесты, можно полагать, что будет. Дней через 7-10, при условии неполной занятости им. Вот тогда можно будет и тестировать, и дорабатывать. И применять.

Для тех, кому нужно установить скрипт, какой есть, и сейчас - версия 2 вариантов скрипта с доработками от 11.12.2006, находится на 2 страницах сайта. Там же - архив (всего 5 КБа, но в будущем он будет дополнен новыми версиями и увеличится в объёме) с обоими скриптами. Демонстрация первого варианта - http://javascript.aho.ru/example/xmp002/falling-snow-en.htm - снежинки и символы, на них похожие, падают, не меняя своих размеров, плавно исчезая в пространстве внизу окна. Второй вариант ( http://javascript.aho.ru/example/xmp002/falling-snow-approach-en.htm ) показывает падение приближающихся к наблюдателю снежинок. Скрипты имеют описания по настройкам - сколько снежинок показывать, их размеры, как вставить свои рисунки. Можно устроить даже падение надписей, ссылок, поздравлений и всего, на что хватит фантазии. (О предложениях по доработке и развитию скрипта пишите на форум сайта.)

Описание по-русски здесь, но версия на данный момент чуть старее.

Уровень: для пользователей

 javascript.aho.ru , © I.Svetlov, 2005-2006 
Текущая очерёдность плана статей (подписчики могут корректировать через голосование).
9. Многуровневое меню с навигацией по наведению мыши.
8. Ключевые слова новых технологий, которые нужно знать разработчику веб-страниц.
3. Как писать тексты с доступом через JS без экранирования специальных символов (< и другие).
4. select и list - в них есть много общего. Как и с меню навигации. Эмулятор селекта.
5. Древовидное меню, подход к данным, отделение данных от представления.
6. Многонедельный календарь со ссылками. (По списку строится календарь.)

Форум сайта рассылки, почта автора рассылки.

 


В избранное