суббота, 27 сентября 2008 г.

Microsoft Degeneration

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




Работая последний год исключительно с продуктами Microsoft и используя в процессе разработки только .NET 2.0 у меня появилось достаточно уверенное и не совсем радостное представление о том, куда движется весь IT нашего времени и какие могут быть последствия дальнейшего усугубления и без того плачевной ситуации на рынке разработки корпоративных систем.
Не думаю, что мое мнение – субъективно и не имеет ничего общего с действительностью, однако вместе с тем отдаю себе отчет в том, что все это, разумеется, частный случай, конкретная ситуация, которая не может характеризовать состояние всего рынка вцелом, а может только указать и отметить лишь отдельные его тенденции. Однако, как известно, правомерность выводов, основанных на индуктивном переходе от частного к общему, в случае огромного количества этого самого «частного» не подлежит никакому сомнению и очевидно является истиной, той самой, которую так отчаянно не хотят замечать ни ярые фанатики редмондского майнстрима, ни те, кто слепо верит, что все хорошо, ни даже те, кто успокаивает себя, что весь этот упадок – это всего лишь наваждение, результат бредней уставшего разума, судорожно пытающегося объяснить происходящее, и не находящего другого, мало-мальски вразумительного объяснения.
Но, не буду забегать вперед раньше времени. Обо всем по порядку.


Ни для кого, разумеется, не секрет, что каждый второй, а может даже и каждый первый, коммерческий корпоративный проект, над которым прямо сейчас, вот в эту сию минуту, трудится бесчисленное множество программистов различной специализации и уровня квалификации, так или иначе, связан с Web.
Как правило, это что-то очень большое, даже громоздкое, очень содержательное, чертовски распределенное и обычно связано между собой какими то разнородными компонентами. Вся эта огромная и тяжелая система, со всеми ее серверами, массивами данных, объектами преобразования и коммуникации, как правило, скрывается за легкой миловидной страничкой браузера. Сейчас это практически архитектура де-факто, и чуть ли не все корпоративные системы сконструированы именно так. Не буду здесь разводить демагогию, почему все именно так, а не иначе или как-нибудь по-другому – это тема совершенно другой направленности, о которой в наше время и так написано много, везде и чуть ли не каждым, кому не лень.
Как правило для построения и разработки подобных систем используются специальные системы и Фреймворки, которые и созданы, как раз для того что бы облегчить создание конечного продукта, уменьшить время и затраты на его разработку и максимально поспособствовать возможности его масштабирования и унификации.
В среде .NET лидером рынка подобных продуктов является Microsoft. Корпорация практически не оставляет никакой возможности конкурентам увеличить или хотя бы отвоевать свою долю влияния в секторе и почти все что только может потребоваться при разработке уже сделано и готово к использованию компаниями-разработчиками. Последним остается только собрать все готовые компоненты воедино, осуществить требуемое взаимодействие между ними, отпрофилировать поведение конечного продукта и наслаждаться полученным результатом.
Создание чего-то нового для решения типовых задач, как например какой-нибудь e-Commerce портал, совсем не нужно. Причин этому две:
1. есть готовые универсальные решения, которые требуется только “напильником” довести до ума;
2. найти или собрать команду квалифицированных профессионалов, способных за достаточно короткое время создать аналогичную существующей систему не так то просто, да и не дешево это, в общем.
Мы живем в эпоху изобилия, в том числе и в ИТ, и как следствие теперь решать “сложные интеллектуальные задачи” по созданию корпоративного ПО может любая домохозяйка, которую обучили основным принципам на двухнедельных курсах. Следовательно, потребность в высококвалифицированных программистах, подобная той, которая была раньше сейчас уже неактуальна: домохозяйка – дешевле. Поэтому многие молодые люди, которые потенциально могли бы вырасти в серьезного специалиста по меркам 90-ых, сейчас в лучшем случае превращаются в “специалистов” по разнообразным системам предлагающим “готовые решения”, которые знают как, где и что применять, какие есть нюансы и тонкости конфигурации каждой из систем. В худшем случае – довольствуются ролью типичной «домохозяйки».
Расти в том смысле, как это было раньше, теперь нет никакого смысла. Деньги платят не за то, что обладаешь серьезной математической и алгоритмической подготовкой, представляешь, откуда берутся биты и как сэкономить пару байт памяти не в ущерб производительности. Деньги платят за то, знаком ли ты с конкретным “готовым решением” и умеешь ли ты сконфигурировать его так, что бы это удовлетворило заказчика и соответствовало всем его требованиям.
Разумеется, я ни в коем случае не хочу сказать, что действительно квалифицированные программисты сейчас не нужны. Конечно нужны, но процентное соотношение таких вакансий, особенно в нашем регионе, ничтожно мало по сравнению с вакансиями “домохозяек” или молодых неопытных студентов. К тому же это не майнстрим, за это не платят много денег, и вообще, что бы добиться существенных результатов нужно приложить неимоверное количество усилий и пройти непростой путь, который к тому же тернист. Не факт, что получится добиться желаемых результатов и достичь поставленных целей. И уж точно не факт, что даже после всего этого, “домохозяйка” из мейнстрима окажется в более плохом финансовом положении. Совсем не факт.
Работая второй год в данной области, я начал ловить себя на мысли, что постепенно и сам превращаюсь в квалифицированную “домохозяйку”. Большую часть своего рабочего времени мне приходится скорее не создавать исходный код, а добавлять или изменять существующую программную модель системы “готового решения”, проводить так называемую “кастомизацию” существующего исходного кода, приводя его в соответствие с требованиями разрабатываемого проекта. Что бы показать высокоинтелектуальность проделываемой мной работы, могу описать, что включает в себя эта “кастомизация”. Добавление новых свойств в существующие объекты и таблицы баз данных, редактирование всевозможных config-файлов, настройка и конфигурация Фреймворка через специальные утилиты, создание новых asp-страниц для добавленной функциональности, выявление причин некорректной работы Фреймворка, появляющихся исключений и дефектов, и прочее и прочее и прочее.
И совершенно другое было бы у меня отношение ко всему тому, чем я занимаюсь, если бы не убогость самих этих систем “готовых решений”. Даже после их установки на сервер, без каких либо дальнейших изменений и модификаций очень часто появляется огромное количество всевозможных проблем, на решение которых порой уходит не один рабочий день. И вместо того, что бы заниматься созданием действительно чего-то нового, приходится большую часть времени тратить на решение данных проблем, тыкание мышкой по разным окнам и диалогам, лицезрение различных сообщений о неправильной конфигурации или недопустимости использования того-то и там-то, необходимости загрузки и установки хот-фикса, без которого функционирование данной системы в принципе невозможно и прочее и прочее и прочее.
Занимаясь такими вещами изо дня в день, все известные языки программирования, методологии и паттерны, эффективные алгоритмы и приемы становятся все менее востребованными и необходимость в их знании уменьшается по экспоненте, мозг забивается “более полезной” информацией о том, например, какую галочку нужно выбрать там-то, что бы все вот это большое и тяжелое работало так как нужно. Где и когда нужно установить какой-нибудь хот фикс, для того что бы избавиться от существующей проблемы, а когда его установка попросту недопустима, потому что иначе все будет работать совсем не так, как требуется. А программирование? Да вы что – настоящие программисты никогда не пишут исходный код, они ленивые и всегда используют только “готовые решения”, изобретать велосипеды – удел дилетантов, да и зачем в наше время уже и так все написано – нужно только уметь этим пользоваться.


Ну что, еще хотите быть преуспевающим и квалифицированным программистом нашего времени? Тогда добро пожаловать в наш мир систем для “домохозяек” и специалистов по скоростному тыканию мышкой. В мир, где больше нет необходимости в написании исходного кода и знания всего того, что требовалось ранее, всех эффективных методологий, алгоритмов, паттернов, приемов и даже языков программирования, теперь это все не нужно и даже более того – противопоказано.
Добро пожаловать в мир Microsoft.

воскресенье, 24 февраля 2008 г.

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

Программирование для многоядерных процессоров делает необходимым поиск решений для абсолютно новых невостребованных ранее задач. Большинство существующих практик проектирования и разработки программного обеспечения не в состоянии максимально эффективно использовать всю потенциальную мощность новых многоядерных систем. Нынешнее программное обеспечение реализовано, как правило, для выполнения на одноядерных платформах и поэтому не в состоянии эффективно использовать несколько ядер. К тому же, использование в подобных программах фиктивного распараллеливания вычислительных процессов еще более усугубляют имеющиеся проблемы эффективности выполнения «одноядерных» приложений на процессорах, имеющих несколько ядер.
Джеймс Рейндерс, автор книги «Intel Threading Building Blocks: Outfitting C++ for Multi-core Processor Parallelism» сформулировал восемь ключевых правил программирования для многоядерных процессоров, которые окажутся очень кстати на пути к увеличению эффективности ваших программ.

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

Правило 2.
Программируйте, используя абстракции. При написании исходного кода сфокусируйтесь на параллельности выполнения процессов, но избегайте непосредственного управления потоками или ядрами процессора. Такие библиотеки, как OpenMP и Intel Threading Building Blocks это все примеры использования абстракций. Не используйте объекты потоков напрямую (pthreads, Windows Threads, Boost threads и пр.) Потоки и MPI это механизмы параллелизма языков программирования. Они предлагают максимум гибкости, однако требуют чрезвычайно много времени для написания, отладки и поддержания. Ваше внимание должно быть сосредоточено на более высоком уровне видения решаемой проблемы, чем уровень управления ядрами и потоками.

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

Правило 4.
Проектируйте вашу систему таким образом, чтобы была возможность не использовать параллелизм вовсе. Для того, что бы проще выполнять отладку, создавайте программу, которую можно было бы запустить без параллельного выполнения задач. В таком случае у вас будет возможность при отладке программы сначала запустить ее с параллельными вычислениями, а затем без таковых и проверить результаты обоих запусков на наличие ошибок и слабых мест. Отладка отдельных частей программы проще, когда в ней нет параллельно работающих фрагментов. Это связано с тем, что основная масса существующих инструментов отладки в большей степени не ориентированы на работу с многопоточным кодом. Когда вам известно, что проблемы возникают только в том случае, когда части системы выполняются параллельно, то наверняка выявить причину этого вам будет проще. Если проигнорировать данное правило и не предусмотреть возможности работы программы в однопоточном режиме, вы можете потратить очень много вермени на выявление причины существующих в программе ошибок. После этого у вас наверняка появится желание добавить в программу возможность ее выполнения в однопоточном режиме, но это уже не принесет такой эффективности, как если бы такая возможность присутствовала изначально. Вам просто необходимо избегать создание параллельных программ, которые для работы обязательно требуют параллельности выполнения. MPI программы часто нарушают это правило, что отчасти является причиной того, что подобные программы сложно отладить.

Правило 5.
Избегайте использования блокировок (lock). Просто скажите блокировкам «нет». Блокировки замедляют программы, снижают их масштабируемость и являются источниками ошибок в параллельном программировании. Делайте неявную синхронизацию решения для вашей программы. Когда вам все-таки требуется явная синхронизация, используйте атомарные операции. Используйте блокировки только как последнее средство. Тщательно спроектируйте вашу систему таким образом, что бы использование блокировок в вашей программе не понадобилось.

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

Правило 7.
Используйте масштабируемые механизмы выделения памяти. Поточные программы требуют использования масштабируемых механизмов выделения памяти. Точка. Существует много решений, которые лучше чем malloc(). Использование таких механимов увеличивает скорость работы программы, устраняя узкие места, связанные с перераспределением памяти и способствуют лучшему использованию системного кеша.

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

Источник: Dr. Dobb's