Распределенные и параллельные вычисления

pic

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

В силу того, что железо различное и несовместимое, попытки хоть как-либо на время такой игры распределить хардверные ресурсы между мощными компьютерами и слабыми тоже не приведут к успеху. Ведь процессоры нельзя распилить ножовкой на кусочки и раздать их нуждающимся. Да и память в виде различных колодок SIMM, DIMM, DDR, RIMM несовместима на различных материнских платах, если не по разъемам, то по тактовой частоте. Я не говорю о том, что даже совпадение частоты — это еще не признак совместимости, поскольку банки памяти могут формироваться либо с соблюдением четности, либо других характеристик и нередко две почти одинаковые колодки RAM в одном компьютере могут стать источником ошибок памяти.

pic

Теперь ясно, что ресурсы компьютеров задаются в железе и распределять его между разными хардверными платформами практически невозможно, за редким исключением полной совместимости. От того, что все компьютеры объединены в локальную вычислительную сеть, толку нет. Потому что она локальная, но далеко не вычислительная. С помощью обычных сетевых решений можно распределять лишь транзит трафика, но никак не ресурсы. А результат налицо — большая часть компьютерной мощности вообще не используется или используется не по назначению. Например, эту статью я набивал в текстовом редакторе. Производительность компьютера для такой работы должна быть на уровне процессора Intel386/33, в то время как у меня стоит Athlon1500XP+. А это означает, что за все время подготовки статьи мой компьютер, по самым грубым и примитивным расчетам, использовал менее половины процента своей тактовой частоты. Более 99,5% ресурсов вообще не использовались. Если еще не учитывать, что в промежутках между нажатиями клавиш компьютер вообще простаивал на все 100%, и не считать перекуров, чаепитий, раздумий и прочих вынужденных пауз, во время которых на экране крутился бестолковый скринсейвер. Но бывают ситуации, когда запущенное прикладное приложение требует гораздо больших ресурсов, чем моя персоналка способна выдать «на гора». Вот если бы можно было те вычислительные ресурсы, которые не использовались ранее, взять и использовать в такие моменты? Не выйдет, ведь при организации работы с помощью персональных компьютеров, даже объединенных в сеть, всегда окажется, что либо ресурсы не используются в достаточной мере, либо их не хватает, а общая производительность в общей сложности не достигает даже 1%. Вот и получается, что, покупая персоналку, мы всегда более чем в 100 раз за нее переплачиваем, да еще и вместе с ней приобретаем различные проблемы, которые пытаемся решить за свой же счет ценой апгрейдов.
Но существуют два пути решения данной проблемы: вычисления параллельные и распределенные. Создать параллельные вычисления — это установить майнфрейм: одна многопроцессорная ЭВМ на всех пользователей, ее производительности хватит для решения самой мощной задачи, которую мы предполагаем на ней выполнять. В этом случае на каждом рабочем месте достаточно установить простейшие терминалы, вычислительные мощности которых почти нулевые, чтобы вывести информацию на экран или печать, а также передать ее к майнфрейму с клавиатуры, мышки или другого манипулятора. Майнфреймовые ЭВМ при кажущейся дороговизне на самом деле в некоторых случаях значительно окупаемы, поскольку при мощности в десятки раз ниже общей производительности объединенных в сеть персоналок можно выполнять задачи, которые на персоналках казались недостижимыми, ведь ресурсы эффективно распределяются. Приобрести такую ЭВМ можно и в Узбекистане, в ряде фирм и компаний, являющихся дилерами крупных производителей майнфреймов. Но здесь есть ряд проблемных моментов, с которыми придется столкнуться:

1. Программное обеспечение. Персоналки еще со времен ZX-Specrum лидировали по разнообразию и охвату задач программным обеспечением по сравнению даже с малыми ЭВМ. Причина проста: производители ЭВМ не стремятся к унификации своей продукции, в результате чего им своими силами приходится создавать софт для своих же железок. У персоналок же в силу их унификации производителей софта на три с лишним порядка больше.

2. Проблема морального старения техники, а с ней и апгрейда. Ведь ни для кого не секрет, что современная техника в своей хардверной конфигурации актуальна примерно в течение трех лет, после чего новые технологии сведут ее на нет. Доапгрейдить персоналку всегда проще, не говоря о том, что ее можно купить и распродать по частям. А если персоналок несколько, то апгрейд можно производить постепенно, вытесняя старый парк машин более современными. Вполне понятно, что окупить ЭВМ стоимостью от нескольких сот тысяч долларов и до нескольких миллионов за столь короткий срок весьма проблематично, если также учесть, что производители ЭВМ комплектуют свою технику далеко не самым гибким и оптимальным образом. В результате к ней приходится приобретать еще и кучу различной и совершенно ненужной периферии, будь то стримеры, флоппи с нестандартной емкостью, приводы уже морально устаревших и не оправдавших себя DVD-ROM и так далее. Все это лишь сильно привяжет вас к продукции и комплектации производителя. Ведь приобрести необходимые комплектующие для ЭВМ в ближайшем магазине оргтехники или на барахолке нереально.

3. Техническое обслуживание. Тут уж ни для кого не секрет, что апгрейд и апдейт персоналки можно произвести буквально на коленке. С ЭВМ такие фокусы не пройдут. Приобрести майнфрейм мало, поскольку к нему еще потребуется и соответствующее сервисное и техническое обслуживание. А это значит, что либо придется вызывать специалистов, которые частенько базируются за рубежом, либо обучать, сертифицировать и содержать свой штат таковых.

Именно удаленность от производителей и сервисных служб делает майнфреймы менее привлекательными у нас в Узбекистане и во многих других странах. В то время как на их родине — в США — майнфреймовая организация вычислений является чуть ли не основной.
Второй путь решения данных проблем — распределенные вычисления. В этом случае персоналки остаются персоналками, сеть сетью и их конфигурация не меняется. А вот в программное обеспечение добавляются функции сетевого распределения объектов. И если какому-то компьютеру не хватает ресурсов для выполнения текущей задачи, то ее фрагменты переносятся по сети на другие компьютеры и там выполняются, после чего результаты вычислений опять же по сети возвращаются на исходное место, откуда была запущена задача.
Параллельные вычисления в одной статье не удастся объяснить не только по принципам действия, но даже перечислить все возможные варианты их реализации. Впрочем, эти тонкости не обязательны ни для конечных пользователей, ни даже для многих разработчиков программного обеспечения. Ведь на каком бы языке программирования ни составлялась современная программа и как бы она линейно ни выглядела, но, тем не менее, при запуске она будет выполняться в режиме параллельных вычислений и на уровне операционной системы и железа процессора. Да и языков программирования, посредством которых можно вмешаться в процесс распараллеливания программ, не так уж много, и их можно пересчитать на пальцах одной руки: Ada, C, Java и, конечно же, Ассемблер.
Зато процесс распределенных вычислений в теории и практике не столь сложен. Современные программы, за небольшим исключением, объектно-ориентированы. Каждый объект содержит в своих полях некую информацию в виде данных, и набор методов для обработки этих самых данных, по сути, представляет собой микрозадачу. Вся программа состоит из отдельных объектов, способных хранить данные, передавать их друг другу и обрабатывать соответствующими методами. Поэтому с объектной точки зрения нет особой разницы в том, где хранить объекты и где их выполнять, будь то локальный компьютер или удаленный. Остается только создать организацию по распределению объектов по сети и сетевому же обмену данных между ними. Для этого на каждом компьютере в вычислительной сети запускается соответствующая программа, посредством которой другие такие же программы могут распределять между собой объекты. Дополнительно на одном из них должен стоять сервер, через который компьютеры находят друг друга. Процесс дальнейшего обмена информацией уже происходит без участия сервера, а напрямую от одной удаленной программы к другой — пиринговые сети (p2p), что служит для повышения производительности.
Когда человек впервые сталкивается с результатами распределенных вычислений, когда Pentium I выполняет задачи, кажущиеся нереальными для Athlon1000, у него создается противоречивое впечатление. И многие пользователи предполагают, что вместо того, чтобы оборудовать одно рабочее место компьютером с процессором тактовой частотой в 1000 мегагерц и 256 мегабайт ОЗУ, проще создать пять рабочих мест из компьютеров с процессорами частотой 200 мегагерц и 64 мегабайтами ОЗУ на каждой. Так ли это или налицо явное заблуждение? На самом деле такая сеть по реальной производительности не сможет заменить один 1000-мегагерцовый компьютер, если их загрузить под завязку. Распределенные вычисления выполняются медленнее, нежели локальные, и требуют больших ресурсов. Ведь задачу необходимо разбить на фрагменты, передать их по сети на другие компьютеры, связать все это воедино и запустить каждый фрагмент на выполнение, получить результаты и опять же по сети отправить их обратно на исходный компьютер. Да и передача информации с одного компьютера на другой по сети значительно медленнее, чем по локальной шине от ОЗУ к процессору и обратно. Поэтому если прогнать тесты на однопроцессорной персоналке, майнфрейме и на распределенной сети, суммарные ресурсы которых равны, то однопроцессорная персоналка всегда покажет лучший результат. Следом идет майнфрейм, который на каждом дополнительном процессоре получает от 80% до 90% прироста производительности от мощности этого самого процессора. И в самом конце теста будут стоять сети с распределенными вычислениями, где прирост производительности от включения дополнительной персоналки примерно составляет только 20% от ее мощности. Это что касается тестов. Совсем иные результаты можно получить, тестируя то же самое оборудование на прикладных задачах. Здесь майнфрейм всегда будет занимать первые места, обгоняя всех своих соперников. С незначительными потерями по мощности прочно займут второе место сети с распределенными вычислениями. А вот персоналка, которая лидировала по тестам, окажется с весьма жалкими прикладными результатами на последнем месте. Почему так происходит? Или тесты врут? Нет, не врут. Секрет фокуса прост: параллельные и распределенные вычисления позволяют более эффективно задействовать неиспользованные ресурсы других компьютеров. Даже в рамках одной большой задачи бывают моменты, когда требуется максимум ресурсов и большая часть их не задействована. Причем моменты минимума случаются намного чаще моментов максимума. Это с точки зрения пользователя компьютер не останавливается, пока выполняет программу. А с точки зрения железа и софта ему периодически приходится ждать и догонять, поскольку обмен данными с накопителями информации и периферией систематически переводит задачи в состояние ожидания (сигнал wait) или в спящий режим (сигнал sleep). И это без учета элементарных простоев оборудования, связанных с человеческим фактором, когда пользователи не работают за включенным компьютером, отвлекаясь на что-либо иное. Проще говоря, загрузить реальными прикладными задачами по максимальной производительности и в течение всего времени работы отдельно взятый персональный компьютер — задача нереальная. А следовательно, в общей сложности и за счет эффективного использования незадействованных ресурсов, по результататам, сеть с распределенными вычислениями, даже несмотря на значительные затраты по передаче данных, тем не менее, способна дать гораздо большую производительность, нежели аналогичная по мощности персоналка. Тесты же загружают ресурсы отдельно взятого компьютера под завязку и проводят процессорные вычисления по максимальной производительности всех ресурсов, без учета обращений к накопителям или периферии, и их цифры имеют отношение только к связке: RAM — CACHE — CPU. Попробуйте создать прикладную задачу, которая будет работать только в этих пределах. Правильно, такие прикладные задачи не существуют, поскольку они никому не нужны! Вычислительная техника не предназначена только для прогона тестов, а потому, если смотреть на это дело через прикладную точку зрения, то оказывается, что тесты вроде бы и рисуют правильные цифры, но только по очень узким предельным параметрам, которые в реальной ситуации абсолютно недостижимы и неприменимы. А посему в данном случае лучше плюнуть на тестовые показатели и оборудовать рабочие места более слабыми компьютерами, тем самым достигая значительной экономии и продлевая срок службы морально устаревшей, но еще работоспособной техники, переводя прикладные задачи на распределенные вычисления.
Что касается темы тестовых показателей, то, конечно же, тесты следует гонять при приобретении оргтехники с целью выявить явные неисправности в железе. Хотя, если техника приобретается, а не собирается, то локализация неисправностей с точки зрения покупателя, потребителя и конечного пользователя теряет всякий смысл, ведь наличие любой ошибки уже является причиной отказа от приобретения. И проверять компьютер следует опять же не с помощью тестов, а с помощью прикладных задач. Для этих целей более всего подходят современные игры. Игра «Хром» позволяет оттестировать компьютер конфигурацией от P-II/RAM-128Mb и до навороченных P-4 и Athlon. Поскольку помимо основного движка она запускает еще и виртуальную машину Java, а та уже в силу заложенных в нее обработчиков исключительных ситуаций вообще не стартует при наличии ошибок не только в железе, но и при кривых драйверах или других коллизиях операционной системы. Для более слабых компьютеров подходят различные версии игры «Quake» от I и до III. Никакие замеры производительности с помощью тестов не способны выдать, а тем более дать пощупать более реальную картину. Более того, тесты своими показателями могут ввести в заблуждение, и компьютер с более высокой тестовой производительностью в реальных прикладных задачах может оказаться слабее другого компьютера, который по тестам получит худшие показатели. Все дело в том, что реальные задачи выполняются не только в железе, но и активно используют систему ввода-вывода информации, проходящую через операционную систему, драйвера, шины, кэши и к периферии. Тестовые же программы используют ввод-вывод только для того, чтобы отобразить конечные результаты, отключаясь от нее на время прогона. Да и следует понять весьма простую истину, заключающуюся в том, что тесты проводятся в расчете на физические ресурсы компьютера, пределы которых заранее выясняются и используются во время прогона. Реальные задачи выполняются в ресурсах виртуальных, а потому прикладная задача может затребовать от системы памяти гораздо больше, чем есть в наличии, и система, пыхтя свопингом, постарается это требование удовлетворить, что приведет к явному снижению производительности.

pic

Осталось только выяснить вопрос о том, как сделать из локальной сети вычислительную? Наверное, многим приходилось встречаться в Интернете с различными благотворительными акциями, предлагающими скачать и установить у себя на компьютере скринсейвер. В описании сообщается, что пока ваш компьютер не используется, запускается хранитель экрана, который в это время производит вычисления для «поиска лекарственных средств от такой сякой болячки» или «обрабатывает сигналы из космоса» с целью вычислить в них послания братьев по разуму из других галактик. Я бы не советовал даже врагу, а не только нашим читателям клюнуть на эту умилительно-слезоточивую благотворительность, поскольку закачка и инсталляция программ сомнительного содержания из Интернета может очень плохо закончиться. В лучшем случае, если вы действительно наткнетесь на распределенные вычисления, причем чаще всего вовсе не относящиеся к медицине или внеземному разуму, а для заработка на попытках решить теорему Ферма или найти большие простые числа, за которые полагаются денежные премии. В худшем случае вы нарветесь на хакеров, которые таким образом решают проблему нехватки вычислительных ресурсов для подбора чужого парольного кода доступа. Еще хуже, если безобидный с виду хранитель экрана с вашего же компьютера попытается получить доступ к конфиденциальной информации на удаленных серверах, и в результате придется иметь дело с Фемидой. Также мало приятного получить за свою наивность свежий апдейт какого-либо вируса. Да и, наконец, какой смысл от такой распределенности, если ее результатами могут воспользоваться только другие, а для вашего компьютера ничего, кроме лишней нагрузки и проблем, выудить не удастся?
Есть более реальный путь — это разработать программное обеспечение с распределенными вычислениями самостоятельно. Что касается языков программирования для этих целей, то следует в первую очередь отметить технологию Java, где соответствующее RMI (Remote Method Invocation) API было реализовано еще в ранних версиях, начиная с 1.1, и используется по сей день во многих сетевых приложениях. Чтобы не загромождать текст излишними эмоциональными восхищениями, лучше перечислю по пунктам основные преимущества применения технологии Java к контексту распределенных вычислений:

1. Интерфейсы RMI просты и понятны, поскольку не вносят чего-либо экзотического или нестандартного в концепцию программирования Java, а потому легко осваиваются и реализуются. Объем текста программ для распределенных вычислений почти не отличается от аналогичного объема для вычислений локальных, и любой уже готовый локальный проект можно запросто переделать в распределенный.

2. Серверная часть RMI не содержит новых решений, а использует уже проверенные и зарекомендовавшие себя службы, работающие по стандартным и даже упрощенным протоколам HTTP или FTP. Впрочем, даже эти сервера могут не понадобиться, если файлы объектов для RMI доступны через расшаренные ресурсы сетевых файловых систем.

3. Максимальная безопасность программирования за счет того, что виртуальная машина Java способна отслеживать различные софтверные и аппаратные коллизии, которые программист может и не предусмотреть, но в то же время при сетевых соединениях их наличие — скорее правило, нежели исключение. О сетевой безопасности Java давно ходят легенды, и мне добавить к сказанному более нечего.

4. RMI-объекты не только эффективно распределяются на удаленных сетевых хостах, но и также эффективно и автоматически уничтожаются там по мере того, как их дальнейшее использование теряет смысл. Тем самым вовремя высвобождаются удаленные ресурсы для выполнения других задач. Виртуальная машина самостоятельно следит за состоянием удаленных объектов, благодаря чему пропадает всякая необходимость в создании и отладке отдельного программного кода для слежения за состоянием локальных и удаленных ресурсов.

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

Ну, а что же остается делать программистам, которые Java не освоили по тем или иным причинам? Писать проекты на своих излюбленных языках программирования, а выполнять в среде JVM, посредством JavaCC (CC — буквально означает компилятор компиляторов). JavaCC — это синтаксический анализатор, с помощью которого можно перевести листинг не Java-программы и выполнить ее в среде виртуальной машины Java. На сегодня существуют готовые реализации листингов, написанных практически для любых современных языков программирования от С++ и до VisualBasic, не говоря о возможности создать свой собственный язык программирования путем разработки правил анализа его выражений.

pic

Программирование — это, конечно же, хорошо, особенно когда вы им виртуозно владеете. Но бессмысленно покупать пианино, когда можно послушать музыку по радио, и нет смысла писать самостоятельно каждое приложение, когда есть множество уже существующих и успешно используемых. Да и не всякий пользователь компьютера — закоренелый программист, хотя всякий программист — пользователь. Для таких случаев можно приобрести готовое программное обеспечение, которое реализует распределенные вычисления для операционной системы в целом, а не отдельных приложений. Для персоналок создано множество различных реализаций под OS Linux, причем как фирменных от Novell или Sun Microsystems, требующих привязку к платформам производителя, так и менее прихотливых от независимых разработчиков. Что касается платформы MS Windows, то от компании Microsoft исходили благие пожелания в адрес пользователей о том, что в данном направлении соответствующее программное обеспечение будет создано. Но не будем забегать вперед, поскольку про сетевые чудеса от Microsoft мы слышали еще во времена намерений создать Windows.NET с целью догнать и перегнать Java. Windows давно есть, а заявленных чудес до сих пор НЕТ. Впрочем, это не проблема, ведь многие приложения MS Windows запускаются прямо в Linux через API-приложения wine. Да и обнаружить в Windows какое-либо приложение, не имеющее лучшей альтернативы в реализации для Linux, практически невозможно.
Думаю, что этой информации вполне достаточно, чтобы читатель мог самостоятельно сделать выводы? Как и во всяком ином деле, результаты распределенных вычислений лучше один раз увидеть, чем сто раз про них услышать или прочитать в сотне статей. А еще лучше использовать. Остался всего лишь один-единственный вопрос: зачем покупать мощную персоналку, когда для достижения гораздо большей производительности более слабую можно завязать в сеть с распределенными вычислениями?

Orphus system