Студопедия
Случайная страница | ТОМ-1 | ТОМ-2 | ТОМ-3
АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатика
ИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханика
ОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторика
СоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансы
ХимияЧерчениеЭкологияЭкономикаЭлектроника

Развитие парадигм программирования

Читайте также:
  1. III. Развитие и искоренение нищеты
  2. O Характерно раннее развитие с быстрым прогрессированием до последней стадии поражения почек.
  3. V. Развитие оборонно-промышленного комплекса
  4. VI этап – современное развитие города.
  5. Алгоритм перепрограммирования.
  6. Аффективное развитие и привязанность
  7. БИЛЕТ № 4.2. ПЕРИОД НОВОРОЖДЕННОСТИ. РЕФЛЕКСЫ НОВОРОЖДЕННЫХ. РАЗВИТИЕ ДВИЖЕНИЙ И ДЕЙСТВИЙ МЛАДЕНЦЕВ

Парадигмы программирования

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

Развитие парадигм программирования

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

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

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

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

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

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

Ценится точность и устойчивость научных расчетов. Язык Фортран — ветеран прикладного программирования, постепенно стал несколько уступать в этой области Паскалю-Си, а на суперкомпьютерах — языкам параллельного программирования, таким как Sisal.

Теоретическое программирование придерживается публикационной направленности, нацеленной на сопоставимость результатов научных экспериментов в области программирования и информатики. Программирование пытается выразить свои формальные модели, показать их значимость и фундаментальность. Эти модели унаследовали основные черты родственных математических понятий и утвердились как алгоритмический подход в информатике. Стремление к доказательности построений и оценка их эффективности, правдоподобия, правильности, корректности и других формализуемых отношений на схемах и текстах программ послужили основой структурированного программирования и других методик достижения надежности процесса разработки программ, например грамотное программирование. Стандартные подмножества Алгола и Паскаля, послужившие рабочим материалом для теории программирования, сменились более удобными для экспериментирования аппликативными языками, такими как ML, Miranda, Scheme, Haskell и другие. Теперь к ним присоединяются нововведения в C и Java.

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

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

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

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

Высокопроизводительное программирование нацелено на достижение предельно возможных характеристик при решении особо важных задач. Естественный резерв производительности компьютеров — параллельные процессы. Их организация требует детального учета временных отношений и неимперативного стиля управления действиями. Суперкомпьютеры, поддерживающие высокопроизводительные вычисления, потребовали особой техники системного программирования. Графово-сетевой подход к представлению систем и процессов для параллельных архитектур получил выражение в специализированных языках параллельного программирования и суперкомпиляторах, приспособленных для отображения абстрактной иерархии процессов уровня задач на конкретную пространственную структуру процессоров реального оборудования.

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

Трансформационное программирование методологически объединило технику оптимизации программ, макрогенерации и частичных вычислений. Центральное понятие в этой области — эквивалентность информации. Она проявляется в определении преобразований программ и процессов, в поиске критериев применимости преобразований, в выборе стратегии их использования. Смешанные вычисления, отложенные действия, "ленивое" программирование, задержанные процессы и т.п. используются как методы повышения эффективности информационной обработки при некоторых дополнительно выявляемых условиях.

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

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

Когнитивный подход с интероперабельным стилем визуально-интерфейсной разработки открытых систем и использование новых аудио-видео средств и нестандартных устройств открывают пути активизации восприятия сложной информации и упрощения ее адекватной обработки.

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

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

 

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

Начнем, пожалуй, с парадигмы Мета-программирования.
Основными идеями этой парадигмы являются возможности расширения базового языка превоклассными (такими, которые смогут использоваться наравне со встроенными) конструкциями, а также всегда программирование на уровне адекватном логике решаемой задачи и предметной области. Мета-программирование поддерживается методологией проектирования и разработки снизу-вверх, при которой сложная система разбивается на уровни, каждый из которых соответствует определенным независимым горизонтальным задачам: от уровня утилит-расширений языка вплоть до уровня доменно-специфического языка для моделирования той или иной прикладной области,— и реализуется постепенно уровень за уровнем. При этом на каждом уровне сложность задачи не увеличивается, поскольку примитивами на нем являются абстракции, выработанные на более низких уровнях.
Таким образом мета-рограммирование порождает концепцию DSL — доменно специфических языков, создаваемых для той или иной предметной области (языко-ориентированное программирование), одновременно и использующими возможности хост-языка и являющимися адаптированными в синтаксисе и семантике к той сфере, для которой они реализованы.
К мета-программным возможностям можно отнести те или иные особенности многих языков. Например, в C это препроцессор, в C++ — в каком-то смысле, перегрузка операторов, а также применение шаблонов для абстракции на уровне системы типов. В Python — это механизм декораторов, позволяющий динамически дополнять реализацию методов. Попытки добавить определенные макросистемы делаются во многих языках. Это, например, MetaLua, а также модули andand, rewrite, rubymacros и др. в Ruby и т.д. Безусловно, базовым языком для парадигмы мета-программирования является Lisp, в котором и зародились (и продолжают зарождатся) ее концепции.

Скриптинговые языки. Можно сказать, что это недопарадигма, поскольку она не основывается на какие-то фундаментальные исследования или принципы. Основная идея тут — максимальное удобство и простота ad-hoc реализации опеределенного класса решений на определенной архитектуре (иными словами, практичность). Это обуславливает такие характеристики языка, как:

- динамичность

- интерпретируемость

- привязка к хост-системе

В рамках этой парадигмы получили свое рождение такие языки, как: Perl (и PHP), Python, Ruby, Tcl, Lua, Basic, JavaScipt, Shell-языки (Bash, PowerShell, ActionScript, AppleScript,...), некоторые из которых впоследствии переросли ее и перешли, как правило, в категорию объектно-ориентированных языков.

Программирование, ориентированное на параллелизм операций.

Это самая новая парадигма и, пожалуй, еще не до конца сформировавшаяся, поскольку пока что нет косенсуса на счет того, какая из предложенных концепций станет общепризнанной (если это вообще произойдет). А это и развитие архитектуры, подобной MapReduce Google, и асинхронная передача сообщений между процессами (полностью без общего состояния) Erlang'а, и использование программной транзакционной памяти — обобщения концепции транзакции в базах данных на любое вычисление (Haskell, Clojure). Основой для выделение этого подхода в отдельную парадигму стало понимание того, что использование блоков для синхронизации параллельных вычислений не является масштабируемым и поддерживаемым решением при реализации многопоточности. Можно провести параллели между этой парадигмой и процедурной: проблема с использованием блоков аналогична проблеме goto. Пока что ясно одно: эта парадигма станет развитием функционального подхода с его краеугольными камнями немутируемых структур данных и ссылочной целостности.

Дуализм типизации. Несмотря на распространенное мнение поддержка языком программирования того или иного вида типизации является ортогональным к парадигме, которую этот язык реализует. Более того, вопрос типизации можно рассматривать в 2-х аспектах: слабая и сильная. Это различие скорее количественное, чем качественное. "Абсолютно" сильная типизация (как это реализовано в Haskell'е) не позволяет никакого приведения типов (во время исполнения). Более слабые системы типизации дают такую возможность до определенной степени. Например, многие источники называют С слабо-типизированным языком, поскольку он позволяет выполнять неявное приведение типов, а также явное приведение указателей (что не дает возможность проверить тип на этапе компиляции). Статическая (проверка типов во время компиляции) и динамическая (проверка на этапе исполнения). Суть динамической типизации можно изложить во фразе из Common Lisp: "у переменных нет типов, типы есть только у значений". Это не значит, что типы не проверяются (как это происходит в нетипизированных языках, тких как Assembler и Forth, но они проверяются при выполнении операций над конкретными значениями во время исполнения программы. Поэтому в динамическом с сильной типизацией Lisp'е не может возникнуть ошибки сегментации памяти при попытке использовать значение не того типа, которая часто встречается в статическом со слабой типизацией С. По мнению идеологов статической типизации, благодаря ее использованию можно исправить большой класс ошибок в программе, связанных с использованием несоответствующих типов, с помощью явного указания типов и их проверки компилятором. А также увеличить быстродействие программы

Программирование на основе стека. Языки на основе стека — это очень простые языки, примитивные операции которых построенны вокруг манипуляции этой структурой данных. Такой подход, в основном, избавляет от необходимости использования переменных для ссылок на значения (point-free programming). Кроме того, синтаксис таких языков становится весьма унифицированным (как правило, используется постфиксная нотация), что дает возможность задействовать мета-программирование. Языками на основе стека являются PostScript и Forth. Кроме того, большинство виртуальных машин современных языков, такие как JVM,.Net CLR, Perl Parrot и т.д. также являются языками основанными на стеке.

Логическое программирование. Это реализация в языке модели формальной логики. При этом результаты работы программы часто являются побочными эффектами логического вывода. Интерес таких языков в том, что они предлагают совершенно иную модель вычислений, чем фон Неймановская архитектура или Лямбда-исчесление Черча, соответственно некоторые задачи, например, связанные с праллельными вычислениями или имеющие четкую математическую модель, можно решать с применением совсем других подходов. В рамках этой парадигмы получили развитие такие концепции, как бэктрекинг и сравнение с образцом (pattern matching).

В заключение перечисления вышеизложенных парадигм хотелось бы упомянуть еще одну парадигму или, скорее, анти-парадигму: эзотерические языки (эзоязыки). Эту концепцию также называют Turing tarpit (бочка дегтя Тюринга), потому что эзоязыки показывают, что можно легко создать Тюринг-полный язык, на котором будет совершенно невозможно программировать. По-моему, это хороший урок для тех, кто утверждает, что язык программирования не имеет значения, знаю 1 язык – легко освоить несколько. Да, на любом Тюринг-полном языке можно реализовать любой алгоритм и любую программу, но поробуйте сделать это на brainfuck'е, использующем только 8 допустимых символов и 8 операций, на котором "Hello world" выглядит так:

++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.

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

Устройства для превращения персональных компьютеров в маленькие суперкомпьютеры известны довольно давно. Ещё в 80-х годах прошлого века на рынке предлагались так называемые транспьютеры, которые вставлялись в распространенные тогда слоты расширения ISA. Первое время их производительность в соответствующих задачах впечатляла, но затем рост быстродействия универсальных процессоров ускорился, они усилили свои позиции в параллельных вычислениях, и смысла в транспьютерах не осталось. Хотя подобные устройства существуют и сейчас — это разнообразные специализированные ускорители. Но зачастую сфера их применения узка и особого распространения такие ускорители не получили.

Но в последнее время эстафета параллельных вычислений перешла к массовому рынку, так или иначе связанному с трёхмерными играми. Универсальные устройства с многоядерными процессорами для параллельных векторных вычислений, используемых в 3D-графике, достигают высокой пиковой производительности, которая универсальным процессорам не под силу. Конечно, максимальная скорость достигается лишь в ряде удобных задач и имеет некоторые ограничения, но такие устройства уже начали довольно широко применять в сферах, для которых они изначально и не предназначались. Отличным примером такого параллельного процессора является процессор Cell, разработанный альянсом Sony-Toshiba-IBM и применяемый в игровой приставке Sony PlayStation 3, а также и все современные видеокарты от лидеров рынка — компаний NVIDIA и AMD.

Для 3D видеоускорителей ещё несколько лет назад появились первые технологии неграфических расчётов общего назначения GPGPU (General-Purpose computation on GPUs). Ведь современные видеочипы содержат сотни математических исполнительных блоков, и эта мощь может использоваться для значительного ускорения множества вычислительно интенсивных приложений. И нынешние поколения GPU обладают достаточно гибкой архитектурой, что вместе с высокоуровневыми языками программирования и программно-аппаратными архитектурами раскрывает эти возможности и делает их значительно более доступными.

На создание GPCPU разработчиков побудило появление достаточно быстрых и гибких шейдерных программ, которые способны исполнять современные видеочипы. Разработчики задумали сделать так, чтобы GPU рассчитывали не только изображение в 3D приложениях, но и применялись в других параллельных расчётах. В GPGPU для этого использовались графические API: OpenGL и Direct3D, когда данные к видеочипу передавались в виде текстур, а расчётные программы загружались в виде шейдеров. Недостатками такого метода является сравнительно высокая сложность программирования, низкая скорость обмена данными между CPU и GPU и другие ограничения.

Вычисления на GPU развивались и развиваются очень быстро. И в дальнейшем, два основных производителя видеочипов, NVIDIA и AMD, разработали и анонсировали соответствующие платформы под названием CUDA (Compute Unified Device Architecture) и CTM (Close To Metal или AMD Stream Computing), соответственно. В отличие от предыдущих моделей программирования GPU, эти были выполнены с учётом прямого доступа к аппаратным возможностям видеокарт. Платформы не совместимы между собой, CUDA — это расширение языка программирования C, а CTM — виртуальная машина, исполняющая ассемблерный код. Зато обе платформы ликвидировали некоторые из важных ограничений предыдущих моделей GPGPU, использующих традиционный графический конвейер и соответствующие интерфейсы Direct3D или OpenGL.

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

Именно поэтому компания NVIDIA выпустила платформу CUDA — C-подобный язык программирования со своим компилятором и библиотеками для вычислений на GPU. Конечно же, написание оптимального кода для видеочипов совсем не такое простое и эта задача нуждается в длительной ручной работе, но CUDA как раз и раскрывает все возможности и даёт программисту больший контроль над аппаратными возможностями GPU. Важно, что поддержка NVIDIA CUDA есть у чипов G8x, G9x и GT2xx, применяемых в видеокартах GeForce серий 8, 9 и 200, которые очень широко распространены. В настоящее время выпущена финальная версия CUDA 2.0, в которой появились некоторые новые возможности, например, поддержка расчётов с двойной точностью. CUDA доступна на 32-битных и 64-битных операционных системах Linux, Windows и MacOS X.


Дата добавления: 2015-07-11; просмотров: 336 | Нарушение авторских прав


Читайте в этой же книге: Области применения параллельных расчётов на GPU. | Возможности NVIDIA CUDA | Решения с поддержкой NVIDIA CUDA | Модель программирования CUDA | Модель памяти CUDA |
<== предыдущая страница | следующая страница ==>
Особенности неспецифичных парадигм применительно к психологии| Разница между CPU и GPU в параллельных расчётах

mybiblioteka.su - 2015-2024 год. (0.014 сек.)