Разделы сайта
Выбор редакции:
- Инструкция, что делать если это произошло с вами
- Загружаем виртуальную машину с флешки программой Virtual Machine USB Boot Виртуальная ос на флешке
- Чем отличается pci express 2
- Основная настройка Netis WF2780
- Поиск музыки по звуку онлайн
- Как откатить версию IOS на iPhone, iPad
- Как сделать яндекс стартовой страницей
- Фитнес-браслеты для Windows Phone
- Подключаем ноутбук к телевизору Настройка подключения пк к ноутбуку
- Что делать если клавиатура ноутбука не работает
Реклама
Обзор языков программирования. Разные языки программирования и их области применения |
В пятидесятые годы двадцатого века с появлением компьютеров на электронных лампах началось бурное развитие языков программирования. Компьютеры, стоившие в то время значительно дороже, чем разработка любой программы, требовали высокоэффективного кода. Такой код разрабатывался вручную на языке Ассемблер . В середине 50-х годов под руководством Джона Бэкуса для фирмы IBM был разработан алгоритмический язык программирования FORTRAN . Несмотря на то, что уже существовали разработки языков, выполняющие преобразование арифметических выражений в машинный код, создание языка FORTRAN (FORmula TRANslator), предоставляющего возможность записи алгоритма вычислений с использованием условных операторов и операторов ввода/вывода, стало точкой отсчета эры алгоритмических языков программирования. К языку FORTRAN предъявлялись требования cоздания высокоэффективного кода. Поэтому многие конструкции языка первоначально разрабатывались с учетом архитектуры IBM 407. Успех разработки этого языка привел к тому, что производители других вычислительных систем стали создавать свои версии трансляторов. С целью некоторой возможной на тот момент унификации языка язык FORTRAN IV, разработанный в 1966 году, стал первым стандартом, именуемым FORTRAN 66. Как альтернатива языку FORTRAN , первоначально ориентированному на архитектуру IBM , под руководством Питера Наура в конце 50-х годов был разработан язык ALGOL ( ALGOrithmic Language ). Основной целью, преследуемой разработчиками этого языка, была независимость от конкретной архитектуры вычислительной системы. Кроме того, создатели языка ALGOL стремились разработать язык, удобный для описания алгоритмов и применяющий систему обозначений, близкую к той, что принята в математике. Языки FORTRAN и ALGOL были первыми языками, ориентированными на программирование вычислений. Язык PL 1, первые версии которого появились в начале 60-х годов, был первоначально ориентирован на IBM 360 и расширял возможности языка FORTRAN некоторыми средствами языка COBOL , разработанного в эти же годы. Несмотря на определенную популярность языка PL/I у программистов, работавших на компьютерах IBM и машинах серии ЕС, в настоящее время он представляет чисто теоретический интерес. В конце 60-х годов под руководством Найарда и Дала был разработан язык Simula-67, использующий концепцию пользовательских типов данных. Фактически это первый язык, применяющий понятие классов. В середине 70-х годов Вирт предложил язык Pascal , который сразу стал широко использоваться. В это же время по инициативе Министерства обороны США началась работа по созданию языка высокого уровня, получившего название Ada – в честь Ады Лавлейс, программистки и дочери лорда Байрона. Создание языка началось с определения требований и выработки спецификаций. Над проектом работали четыре независимые группы, но все они использовали как основу язык Pascal . В начале 80-х годов был разработан первый промышленный компилятор языка Ada . Универсальный язык программирования С был разработан в середине 70-х годов Денисом Ритчи и Кеном Томпсоном. Этот язык стал популярным языком системного программирования и в свое время использовался для написания ядра операционной системы UNIX . Стандарт языка С начал разрабатываться рабочей группой института стандартов ANSI в 1982 году. Международный стандарт языка С принят в 1990 году. Язык С лег в основу разработки языков программирования C++ и Java . Наряду с алгоритмическими языками параллельно развивались и языки, предназначаемые для обработки деловой информации, а также языки искусственного интеллекта. К первым относится язык COBOL (COmmon Business Oriented Language ), а ко вторым – языки LISP ( LISt Processing ) и Prolog. Язык LISP , разработанный в 60-х годах под руководством Дж. Маккарти, был первым функциональным языком обработки списков, который нашел широкое применение в теории игр. С появлением персональных компьютеров языки стали составными частями интегрированных сред разработки. Появились языки, применяемые в различных офисных программах, например VBA ( Visual Basic for Application ). В 90-х годах с распространением сети Интернет расширяется возможность распределенной обработки данных, что отражается и на развитии языков программирования. Появляются языки, ориентированные на создание серверных приложений, такие как Java , Perl и PHP , языки описания документов – HTML и XML . Традиционные языки программирования С++ и Pascal также претерпевают изменения: под языком программирования начинает пониматься не только функциональность самого языка, а также библиотеки классов, предоставляемые средой программирования. Акцент со спецификации самих языков программирования переносится на стандартизацию механизмов взаимодействия распределенных приложений. Появляются новые технологии – COM и CORBA , специфицирующие взаимодействие распределенных объектов. Области применения языков программированияВ настоящее время языки программирования применяются в самых различных областях человеческой деятельности, таких как:
С течением времени одни языки развивались, приобретали новые черты и остались востребованы, другие утратили свою актуальность и сегодня представляют в лучшем случае чисто теоретический интерес. В значительной степени это связано с такими факторами, как:
Кроме использования комментариев для получения параллельной программы, часто идут на расширение существующих языков программирования. Вводятся дополнительные операторы и новые элементы описания переменных, позволяющие пользователю явно задавать параллельную структуру программы и в некоторых случаях управлять исполнением параллельной программы. Так язык High Performance Fortran (HPF), помимо традиционных операторов Фортрана и системы спецкомментариев, содержит новый оператор FORALL, введенный для описания параллельных циклов программы. Наиболее интересной чертой HPF представляется многоуровневое отображение массив - массив-шаблон - виртуальный процессорный массив - физические процессоры, позволяющее максимально гибко отображать пользовательские данные на реальный компьютер. Другим примером служит язык mpC, разработанный в Институте системного программирования РАН как расширение ANSI С. Основное назначение mpC - создание эффективных параллельных программ для неоднородных вычислительных систем. Пользователь может задать топологию сети, распределение данных и вычислений и необходимые пересылки данных. Посылка сообщений организована с использованием интерфейса MPI. DVM-система предназначена для создания переносимых и эффективных вычислительных приложений на языках C-DVM и Fortran-DVM для параллельных компьютеров с различной архитектурой. Аббревиатура DVM соответствует двум понятиям: Distributed Virtual Memory и Distributed Virtual Machine. Первое отражает наличие единого адресного пространства. Второе отражает использование виртуальных машин для двухступенчатой схемы отображения данных и вычислений на реальную параллельную машину. Модель программирования предполагает задание DVM-указаний с помощью спецкомментариев, а значит, один вариант программы для последовательного и параллельного исполнения. Поддерживаются три группы директив: директивы распределения данных, директивы распределения вычислений и спецификации удаленных данных. Компилятор переводит программу на язык Фортран или Си, используя для организации межпроцессорного взаимодействия одну из существующих технологий параллельного программирования (MPI, PVM, Router). В систему DVM также входят библиотека поддержки LIB-DVM, DVM-отладчик, предсказатель выполнения DVM-программ, анализатор производительности DVM-программ. Система разработана в Институте прикладной математики им. М.В.Келдыша РАН. Специальные языки программирования Если нужно точнее отразить либо специфику архитектуры параллельных систем, либо свойства какого-то класса задач некоторой предметной области, то используют специальные языки параллельного программирования. Для программирования транспьютерных систем был создан язык Occam, для программирования потоковых машин был спроектирован язык однократного присваивания Sisal. Очень интересной и оригинальной разработкой является декларативный язык НОРМА, созданный под руководством И.Б.Задыхайло в Институте прикладной математики им. М.В.Келдыша РАН для описания решения вычислительных задач сеточными методами. Высокий уровень абстракции языка позволяет описывать задачи в нотации, близкой к исходной постановке проблемы математиком, что условно авторы языка называют программированием без программиста. Язык с однократным присваиванием, не содержит традиционных конструкций языков программирования, фиксирующих порядок вычисления и тем самым скрывающих естественный параллелизм алгоритма. Библиотеки и интерфейсы, поддерживающие взаимодействие параллельных процессов С появлением массивно-параллельных компьютеров широкое распространение получили библиотеки и интерфейсы, поддерживающие взаимодействие параллельных процессов. Типичным представителем данного направления является интерфейс Message Passing Interface (MPI), реализация которого есть практически на каждой параллельной платформе, начиная от векторно-конвейерных супер-ЭВМ до кластеров и сетей персональных компьютеров. Программист сам явно определяет какие параллельные процессы приложения в каком месте программы и с какими процессами должны либо обмениваться данными, либо синхронизировать свою работу. Обычно адресные пространства параллельных процессов различны. В частности, такой идеологии следуют MPI и PVM. В других технологиях, например Shmem, допускается использование как локальных (private) переменных, так и общих (shared) переменных, доступных всем процессам приложения, и реализуется схема работы над общей памятью с помощью операций типа Put/Get. Несколько особняком стоит система Linda, добавляющая в любой последовательный язык лишь четыре дополнительные функции in, out, read и eval, что и позволяет создавать параллельные программы. К сожалению, простота заложенной идеи оборачивается большими проблемами в реализации, что делает данную красивую технологию скорее объектом академического интереса, чем практическим инструментом. Параллельные предметные библиотеки Часто на практике прикладные программисты вообще не используют никаких явных параллельных конструкций, обращаясь в критических по времени счета фрагментах к подпрограммам и функциям параллельных предметных библиотек. Весь параллелизм и вся оптимизация спрятаны в вызовах, а пользователю остается лишь написать внешнюю часть своей программы и грамотно воспользоваться стандартными блоками. Примерами подобных библиотек являются Lapack, ScaLapack, Cray Scientific Library, HP Mathematical Library, PETSc и многие другие. Некоторые параллельные предметные библиотеки BLAS и LAPACK - библиотеки, реализующие базовые операции линейной алгебры, такие как перемножение матриц, умножение матрицы на вектор и т.д. ScaLAPACK включает подмножество процедур LAPACK, переработанных для использования на MPP-компьютерах, включая: решение систем линейных уравнений, обращение матриц, ортогональные преобразования, поиск собственных значений и др. FFTW, DFFTPack - быстрое преобразование Фурье. PETSc - набор процедур и структур данных для параллельного решения научных задач с моделями, описываемыми в виде дифференциальных уравнений с частными производными. Специализированные пакеты и программные комплексы И, наконец, последнее направление, о котором стоит сказать, это использование специализированныю пакетов и программныю комплексов. Как правило, в этом случае пользователю вообще не приходится программировать. Основная задача - это правильно указать все необходимые входные данные и правильно воспользоваться функциональностью пакета. Так, многие химики для выполнения квантово-химических расчетов на параллельных компьютерах пользуются пакетом GAMESS, не задумываясь о том, каким образом реализована параллельная обработка данных в самом пакете. Написание большинства современных компьютерных программ осуществляется при задействовании языков высокого уровня. Примечательно, что многие из них были разработаны еще в 60 и 70-х годах, но актуальны до сих пор. Какие еще факты о высокоуровневых языках мы можем отметить? Каковы наиболее распространенные разновидности соответствующих решений? Сущность высокоуровневых языков написания программЯзык программирования высокого уровня — инструмент, относящийся к категории машинно-независимых. Что это означает? Дело в том, что языки программирования делятся на несколько категорий. Есть машинный код: набор алгоритмов, что предназначены для управления пользователем непосредственно аппаратными элементами компьютера. Их сущность будет полностью машинно-зависимой: для конкретных типов ПК подойдут только определенные алгоритмы. Есть языки ассемблера. По сути дела, они являются надстройкой над теми, что предназначены для низкоуровневого управления аппаратными компонентами ПК посредством машинного кода. Но по многим признакам языки ассемблера также принято относить к машинно-зависимым. Как правило, они адаптированы к конкретной разновидности аппаратного компонента ПК. Их основная задача — упростить пользователю управление компьютером посредством соответствующих низкоуровневых коммуникаций. В свою очередь, язык программирования высокого уровня позволяет осуществлять пользователю взаимодействие с ПК вне зависимости от того, какое конкретно оборудование установлено на компьютере. Поэтому его следует относить к машинно-независимым. При написании операционных систем чаще всего задействуется язык программирования высокого уровня. Но есть ОС, что написаны на ассемблере. Языки программирования низкого и высокого уровня могут использоваться одновременно. Человек, отдавая ПК высокоуровневые команды, должен, так или иначе, доносить их до конкретных аппаратных компонентов, и эта функция может быть реализована при использовании языков ассемблера одновременно с высокоуровневыми, что задействованы в структуре операционной системы. ТрансляторыВажнейшие элементы, что входят в языки программирования высокого уровня, — трансляторы. Их функция может быть разной. В числе ключевых областей применения трансляторов — «перевод» команд, формируемых на языке программирования высокого уровня, в машинный код, понятный конкретному аппаратному компоненту ПК, например, процессору. Трансляторы, выполняющие данную функцию, именуются также компиляторами. Есть другая разновидность соответствующих компонентов — интерпретаторы. Они предназначены, в свою очередь, для «перевода» высокоуровневых команд в те, что понятны операционной системе или какой-либо программе. Классификация высокоуровневых языковВысокоуровневые языки программирования могут быть классифицированы по разным основаниям. Распространена схема, по которой они делятся на следующие основные разновидности: Процедурно-ориентированные (задействуются в качестве инструмента при обработке информации на любом этапе вычислений); Проблемно-ориентированные (используются как средство решения отраслевых и прикладных задач, формируемых при расширении областей применения ПК); Объектно-ориентированные (могут быть частными случаями языков первых двух типов, однако, адаптируются к пользованию широким кругом разработчиков с разным уровнем подготовки, например, в виде решения с визуальным интерфейсом). Рассмотрим теперь некоторые исторические и современные языки программирования высокого уровня, соответствующие данной классификации. Процедурно-ориентированные языкиК таковым можно отнести Фортран. Он считается первым языком программирования высокого уровня, созданным для широкого применения. Характеризуется простой структурой. К процедурно-ориентированным языкам также относится Бейсик. Считается одним из самых часто используемых при обучении программированию. Пример другого процедурно-ориентированного языка — СИ. Изначально он создавался для ОС UNIX. На его основе впоследствии был создан язык C++, дополненный инструментами объектно-ориентированного программирования. Еще один язык, относящийся к рассматриваемой категории — Паскаль. Часто также задействуется при обучении программированию. Возможности данного языка позволяют его использовать как очень мощный инструмент разработки профессиональных видов ПО. Проблемно-ориентированные языкиК таковым можно отнести Лисп, Пролог. Первый язык был разработан в 1962 году — спустя несколько лет после создания Фортрана. Рассматривается, таким образом, как второй в истории. Активно задействовался в качестве инструмента работы программистов со строками символов. На практике Лисп использовался в системах, классифицируемых как экспертные, а также те, что предназначались для аналитических вычислений. Пролог нашел широкое применение в области логического программирования. На практике чаще всего задействуется в управлении алгоритмами искусственного интеллекта в соответствующих системах. Объектно-ориентированные языкиИзучим теперь примеры языков программирования высокого уровня, которые относятся к категории объектно-ориентированных. В числе таковых — Visual Basic, Delphi, Visual Fortran, отмеченный выше C++, а также Prolog ++. Фактически все они в своей основе содержат процедурно-ориентированные языки. Однако предполагается существенное их дополнение визуальными элементами управления с целью последующего освоения необходимых алгоритмов разработчиками, привыкшими к другим инструментам. Так, первый язык программирования высокого уровня — Фортран — может быть в оперативные сроки изучен IT-специалистами посредством возможностей Visual Fortran. Аналогичным методом можно быстро освоить Бейсик или Пролог. Осуществляется, в свою очередь, при использовании Delphi программирование на языке высокого уровня Object Pascal. Существует большое количество иных сред разработки ПО, классифицируемых как объектно-ориентированный язык. Данная сфера технологий разработки ПО активно развивается. Фортран и Лисп — первый и второй высокоуровневые языкиИзучим подробнее то, как появился первый язык программирования высокого уровня — Фортран, а также Лисп, считающийся вторым. В 1954 году разработчики из компании IBM, возглавляемые Джоном Бэкусом, создали язык, посредством которого программисты получили возможность значительно облегчить взаимодействие с ПК, которое до того момента осуществлялось посредством машинных команд либо ассемблера. Он получил название Fortran и вскоре стал известен и в СССР под русифицированным наименованием. Фортран стал популярным инструментом для научных вычислений. Основным революционным элементом, предложенным специалистами IBM сообществу, стал, собственно, тот самый компилятор, призванный быть альтернативой ассемблеру. В первые годы практики написания программ при использовании Фортран многие разработчики считали компилятор не вполне удачным решением, прежде всего, с точки зрения трудозатрат. Многие машинные коды, действительно, составлялись проще, чем при задействовании транслятора. Однако по мере стремительного увеличения производительности компьютеров программисты начинали осознавать, что без использования компилятора эффективное ПО, которое будет полностью задействовать вычислительные мощности ПК, создавать крайне проблематично. Так, начинания разработчиков из IBM получили дальнейшее развитие. Основные синтаксические конструкции языка программирования высокого уровня Фортран во многих случаях стали задейстоваться в качестве базовых при создании новых решений. Примером достижения практических результатов в области развития концепций, заложенных в Фортран, можно считать создание Лисп. Данный язык был разработан в 1958 году, однако, широкую известность он приобрел несколько позже — в 1960-м. Лисп был разработан Джоном Маккарти и опубликован в одном из популярных журналов для IT-специалистов. Основное предназначение рассматриваемого языка — обработка списков. Лисп стал популярен в среде разработчиков систем искусственного интеллекта. На его основе были созданы такие языки, как Planner, Scheme, а также Common Lisp. Также Лисп оказал значительное влияние на многие современные инструменты разработки ПО. Структура языков программирования высокого уровня, популярных сегодня, в значительной степени базируется на алгоритмах Фортран и Лисп. Интересно будет, однако, рассмотреть иные подходы к классификации рассматриваемых инструментов разработки средств ПО. Универсальные высокоуровневые языкиТак, современные эксперты выделяют универсальные высокоуровневые языки. К ним относятся, в частности, те, что были разработаны в 60-е годы. Ключевые их характеристики: Ориентация на широкий спектр задач (прежде всего, относящихся к вычислительным); Большое количество языковых конструкций и алгоритмов; Значимость не только для своего времени, но и для современного этапа развития компьютерной техники; Поддержка в соответствующих языках императивной методологии. Универсальные языки — основополагающие в соответствующей отрасли IT-разработки. Можно отметить, что до сих пор они не имеют прямых аналогов в части внутренней структуры. Собственно, это во многом объясняет актуальность задействования соответствующих языков в современных объектно ориентированных интерфейсах. Также общее в отмеченных языках — тип данных. Этот фактор в значительной степени предопределяет их универсальность. В числе наиболее примечательных свойств языков, относящихся к категории универсальных — преемственность. Так, исторически более поздние языки, как правило, базировались на концепциях предшественников. Уникальные языкиНекоторые IT-эксперты выделяют в самостоятельную категорию «уникальные языки». В числе таковых: APL, Cobol, Forth, SETL, а также CLU. Какова их специфика? Важнейший аспект APL — задействование массивов (векторов и матриц) в качестве ключевого структурного типа. Специфика языка Cobol — в ориентированности на коммерческую сферу. Так, его целесообразно задействовать при решении задач, связанных со стандартизированным форматом представления результатов. Язык Forth характеризуется использованием постфиксной записи программ, а также задействованием стековой нотации. В языке SETL применяются совокупности значений в качестве одного из ключевых типов данных. Языком программирования высокого уровня является также CLU. Его основная особенность — задействование концепции работы с абстрактными типами данных. Многие IT-специалисты видят логичным появление новых решений, базирующихся на уникальных языках — таких как, например, Object-Oriented Cobol. Средства параллельного программированияДанная категория может включать огромное количество решений. В свою очередь, языки параллельного программирования могут иметь большое количество оснований для классификации. Например, метод организации процессов. Данное основание предполагает классификацию средств параллельного программирования исходя из наличия в них: Сопрограмм; Разветвлений; Объединений; Параллельных скобок; Алгоритмов работы с процессами. Другое основание для классификации языков рассматриваемого типа — методы синхронизации процессов. Соответствующие решения могут, таким образом, включать: Семафоры; Мониторы; - «рандеву»; Критические участки; Дистанционный вызов процедур; Транзакции, относящиеся к категории атомарных. К языкам рассматриваемого типа относятся Modula-2, BLISS, Concurrent Pascal, DP, Argus. Семейство языков CВыше мы рассмотрели в качестве примера языка высокоуровневого программирования такое решение, как C. По сути дела, оно формирует целое семейство. Языки, принадлежащие к нему, являются частными конструкциями C. Так, его дополнение различными объектно-ориентированными компонентами привело к разработке C++. После существенной фильтрации ряда конструкций C появился язык Java. Можно отметить, что Java создавался во многом под влиянием концепций проекта Oberon, которым руководит Никлаус Вирт, создатель языка Паскаль. Относится ли к высокоуровневым JavaScript? Безусловно, да, несмотря на узость применения — в качестве инструмента разработки веб-страниц. Но к языкам программирования высокого уровня не относятся, в частности, HTML, XML и SGML. Они классифицируются как инструменты разметки гипертекста. Семейство языков PascalЯзыки программирования высокого уровня Pascal также образуют отдельное семейство. На базе Паскаль был, собственно, создан Oberon, классифицируемый как язык объектно-ориентированного типа. Ключевая особенность Oberon — в возможности обеспечения безопасности типов. Не считая Oberon, к языкам семейства Pascal можно отнести Modula-2, а также Component Pascal. Семейство языков AdaОсновополагающий в соответствующей категории языков — заказанный под нужды Министерства обороны США Ada. Он был создан в конце 70-х — начале 80-х годов. Характеризуется большим количеством функций, возможностей, универсальностью. Семейство языков Ada включает такие решения, как Cedar, Modula 3. Семейство языков SimulaЯзык Simula распространен в отраслях программирования, связанных с имитационным моделированием. Специфика соответствующих решений — в задействовании специфического ядра. Его использование позволяет применять различные расширения, адаптированные к тем или иным сферам применения. На основе Simula были созданы объектно-ориентированный язык Smalltalk, а также BETA, характеризующийся способностью комбинировать в рамках единой абстракции алгоритмы, отражающие работу с данными, процедурами, а также управление. Объекты BETA могут рассматриваться в различном контексте, например, в качестве переменных, функций или параллельных систем. Для решения вычислительных задач сейчас все активнее используются графические процессоры, но до сих пор открыт вопрос: как писать эффективные программы под соответствующие конфигурации? 15.06.2011 Андрей Адинец Для решения вычислительных задач сейчас все активнее используются графические процессоры, но до сих пор открыт вопрос: как писать эффективные программы под соответствующие конфигурации? Стандартное решение - связка CUDA или OpenCL - позволяет сравнительно быстро реализовать алгоритм, однако создать оптимизированную под конкретную конфигурацию версию с их помощью сложно. Требуются инструменты для программирования графических процессоров более высокого уровня, которые могут быть созданы, например, при помощи расширяемых языков. Еще три года назад графические процессорные устройства (Graphical Processing Unit, GPU) рассматривались лишь как видеокарты для ПК, то сейчас отношение к ним изменилось - появились специальные серверные модели GPU, ориентированные на решение вычислительных задач, увеличилась производительность на вычислениях с двойной точностью, возникли системы рекордной производительности, занимающие высшие строки в Top500 . А как писать эффективные программы под такие машины? Стандартный ответ - связка CUDA или OpenCL для программирования GPU и MPI на уровне кластера. Эти инструменты доступны, активно поддерживаются производителями оборудования, под них уже написано много программ, однако есть и недостатки. CUDA и OpenCL - расширения языка Си, они не сложны для изучения, хотя и являются достаточно низкуровневыми инструментами. С их помощью можно сравнительно быстро реализовать алгоритм для GPU, однако создать оптимизированную под конкретное приложение и конфигурацию версию оказывается значительно сложнее. Все оптимизации потребуется выполнять вручную, что приведет к увеличению размера кода и ухудшению его читаемости. И хотя программы, созданные при помощи OpenCL, будут переносимыми между широким спектром архитектур, производительность при таком переносе не сохранится. Требуются инструменты для программирования GPU более высокого уровня. Создавать такие инструменты можно разными путями: вводить новый язык программирования; добавлять директивы в уже существующий язык, как делается в модели PGI Accelerator или CAPS HMPP; воспользоваться расширяемыми языками. Расширяемые языки - языки программирования, синтаксис и семантика которых не фиксированы, а могут быть изменены в зависимости от потребностей программиста. По сравнению с традиционными, расширяемые языки обладают рядом преимуществ: в них проще добавлять новые возможности; они открыты; изучение новых моделей программирования на основе таких языков проще, поскольку требуется изучить лишь сравнительно небольшие по объему расширения; с помощью таких языков легче выполнять тонкую настройку и оптимизацию программ. Расширяемые языкиДля того чтобы язык был расширяемым, необходимо чтобы в нем присутствовали:
Оказывается, что языков, удовлетворяющих этим требованиям, сравнительно немного: Lisp, Nemerle , Seed7, xoc и Stratego. При этом xoc, который предназначен для расширения языка Си, использует отдельный язык Zeta для написания расширений, а Stratego - это язык предметной области для создания преобразователей исходного кода. Nemerle - расширяемый язык, использующий среду. Net. Все расширяемые языки поддерживают механизмы для работы с деревом программ, и прежде всего это конструкция квазицитирования - спецификации объекта, представляющего дерево программы, при помощи самого исходного кода. В языке Nemerle для этого используется конструкция, например создает дерево, состоящее из объявления переменной i с начальным значением 0. Квазицитирование похоже на создание строковых объектов при строковых константах. На рис. 1 приведен пример квазицитирования. Конструкция интерполяции позволяет подставлять значения переменных в фиксированный шаблон внутри квазицитирования. В Nemerle для этого используются конструкции $(...), если требуется подставить список, например. Также в расширяемых языках присутствуют конструкции разбора дерева программы. В языке Nemerle для этого используется оператор match(...) { ... }, аналог switch из языка Си, в качестве веток которого используются конструкции квазицитирования. При этом интерполяция трактуется как объявление новых переменных, которые в случае успешного сопоставления получают значения соответствующих поддеревьев. Например, для оператора сопоставления match(e) {| => ... }, если e содержит дерево, в переменную a попадет, а в переменную b . Средства для работы с деревом программы используются в конструкциях расширения языка. В языке Nemerle таковыми являются макросы - специальные функции, выполняемые на этапе компиляции и возвращающие фрагмент дерева программы, который подставляется на место их вызова. При этом макрос принимает фрагменты программы в качестве параметров, и может их преобразовывать. В принципе, вызывать макрос можно точно так же, как и обычную функцию; но более интересной возможностью является привязка вызова макроса к специальному синтаксису. Это позволяет вводить в язык Nemerle новые синтаксические конструкции и таким образом расширять язык. На рис. 2 приведен пример макроса с синтаксическим расширением, позволяющий объявить многомерный цикл с переменными и количеством итераций по каждому измерению, а на рис. 3 дан пример преобразования программы, которое осуществляет этот макрос. Заметим, что макрос, осуществляющий такое расширение, занимает менее 30 строк исходного кода и при этом включает несколько проверок на ошибки. При традиционном подходе реализация такого расширения потребовала бы значительно большего количества кода и, кроме того, потребовала бы изучения внутреннего устройства компилятора. Исторически первым появился механизм макросов в Лиспе, программа в котором представляется как обычный список и не требует специальных конструкций для работы с деревом программы, поэтому именно в этом языке расширяемое программирование получило наибольшее распространение. Макросы в Nemerle аналогичны таковым в Лиспе. В системе xoc механизм расширений реализован через расширения грамматики и атрибуты дерева разбора. Любое расширение обязательно задает два атрибута: тип синтаксической конструкции и выражение на базовом языке, в которое она преобразуется. Для расширяемых языков характерна реализация через макросы многих стандартных конструкций. В языке Nemerle все циклы и условные операторы, кроме match, реализованы через макросы, а в Лиспе макросами являются стандартные конструкции циклов и объявления функций. Как использовать языки?Для расширяемого языка программирования можно написать конструкции, позволяющие наиболее удобным способом программировать графические процессоры, что и было сделано в рамках проекта NUDA (Nemerle Unified Device Architecture), целью которого является создание расширений языка Nemerle для программирования GPU. В качестве интерфейса взаимодействия с GPU и целевого языка для представления программы используется OpenCL. Для начала надо реализовать исполнение на GPU подмножества кода на языке Nemerle. При этом должны поддерживаться привычные операторы языка, такие как циклы и ветвления, а также работа с простыми типами данных, структурами и массивами. Код для GPU выносится в отдельные функции, или в ядра NUDA. Каждое ядро отмечается макросом nukernel, который по коду ядра генерирует код на OpenCL и метод-заглушку для вызова ядра на стороне хоста. Перед генерацией кода производится раскрытие всех макросов, за исключением макросов циклов и ветвления. Если внутри ядра требуется вызвать функцию, эта функция должна быть помечена макросом nucode, который сгенерирует для этой функции код на языке OpenCL. Вызов ядра осуществляется при помощи макроса nucall; помимо параметров ядра, ему передается еще и конфигурация решетки потоков, с которой оно запускается. Чаще всего в качестве ядра для GPU используется тело цикла, поэтому хотелось бы сразу переносить цикл на GPU. В Nemerle это можно реализовать - соответствующий макрос в NUDA называется nuwork. В качестве обязательных параметров он принимает размер блока потоков и на основании текущего контекста и анализа кода тела цикла определяет набор переменных, которые необходимо передать ядру в качестве параметров. Тело ядра формируется из тела цикла, вычисления индексов цикла через глобальный номер потока, а также условия, позволяющего корректно исполнять цикл даже в том случае, когда глобальный размер сетки не делится на размер группы потоков. На место цикла подставляется вызов макроса nucall, осуществляющий вызов сгенерированного ядра. В принципе можно разрешить использовать в GPU-программах обычные массивы языка Nemerle, но это приводит к высоким накладным расходам - массив требуется копировать в память GPU при каждом вызове ядра, а затем копировать обратно. Поэтому в программах для GPU используются специальные типы-массивы с ленивой синхронизацией между GPU и CPU. Это позволяет, с одной стороны, не загромождать текст программы командами копирования данных, а с другой - избежать накладных расходов на копирование данных. Для таких массивов, как и для обычных массивов в Nemerle, используется управление памятью при помощи сборки мусора. Для выделения памяти под такие массивы существует макрос nunew, который надо применить к обычному оператору выделения памяти. На рис. 4 слева приведена обычная программа сложения массивов, а справа - аналогичная программа, но выполняющая вычисления на GPU. Получить GPU-программы из обычной достаточно просто - требуется лишь применить макросы к циклам и операциям выделения памяти, при этом объем кода практически не меняется. Программа, написанная с использованием NUDA, занимает менее 20 строк кода. Аналогичная программа, но на чистом языке Си и OpenCL занимает более 100 строк. Помимо макросов, облегчающих работу с GPU, система расширений NUDA включает также аннотации для преобразования циклов. Аннотации, по сути, являются специальными макросами. Например, аннотация inline применяется к циклу с фиксированным числом итераций и выполняет его полную развертку. Аннотация dmine выполняет глубокую развертку цикла. “Глубокая развертка” означает, что создание нескольких копий тела цикла и перемешивание выполняются не только для самого преобразуемого цикла, но и для вложенных циклов, если они независимы. ЭффектДля чего программисту нужно учить новый язык и осваивать новые библиотеки расширяемых языков? Основной ответ - продуктивность. Имея алгоритм из параллельных циклов, работающих с массивами и записанный на языке Nemerle, достаточно добавить несколько аннотаций, чтобы получить программу для GPU. При этом программа будет исполняться на любом устройстве с поддержкой OpenCL, включая графические процессоры nVidia и AMD, а также процессоры x86. Чтобы добиться того же с помощью только технологий OpenCL или CUDA, потребуется затратить значительно больше ресурсов, которые уйдут не только на написание исходного кода, но и на отладку взаимодействия между хостом и GPU. Другая причина - производительность созданного кода. На CUDA или OpenCL преобразования циклов потребуется выполнять вручную, причем отдельно для каждой архитектуры. Это долгий и чреватый ошибками процесс, а полученный в результате код трудночитаем и неудобен для сопровождения. С NUDA эту работу можно делать при помощи аннотаций. Например для нескольких ядер можно оптимизироватьации операции свертки изображений или умножения матриц при помощи аннотаций inline и dmine. Без увеличения размера исходного кода удается добиться повышения производительности в два–пять раз. При этом, если бы те же самые преобразования выполнялись вручную, это привело бы к увеличению кода в разы, а иногда и на порядок, не говоря уже о затратах времени на отладку и подбор оптимальных параметров развертки. Например, универсальная аннотированная программа из семи строк в NUDA умножения транспонированной матрицы на матрицу с двойной точностью выполняется на nVidia Tesla C2050 лишь на 40% медленнее самой быстрой в настоящий момент реализации (CUBLAS 3.2). Аналогичная программа, написанная вручную, заняла бы 70 строк кода. Естественно, для стандартных задач можно один раз вручную написать код, чтобы повысить производительность, но для специфических задач снижение трудозатрат и повышение продуктивности будет очень кстати. Наконец, повышение продуктивности относится и к созданию самих расширений: создавать их при помощи расширяемых языков проще, чем с помощью традиционных инструментов. Вся система NUDA, несмотря на свою функциональность, занимает всего лишь 12 тыс. строк кода, не считая тестов. Это сравнительно немного, например, компилятор языка Nemerle (сборка 9025) занимает около 130 тыс. строк. Расширяемый язык - это мощный инструмент, и его использование в параллельных вычислениях находится пока в самом начальном состоянии. В области разработки параллельных языков программирования имеется очень много интересных задач, и любую из них можно решить при помощи сочетания расширений и библиотек. Можно добавить в язык асинхронные блоки кода и параллельные циклы, можно создать удобные конструкции для программирования кластерных систем, такие как распределенные массивы. Наконец, можно при помощи расширений построить полноценный язык параллельного программирования, такой как Chapel или X10. Андрей Адинец ([email protected]) - м.н.с. НИВЦ МГУ (Москва). Компьютерные программы часто описываются как “наборы инструкций”, и компьютерные языки воспринимаются многими только как словарный и синтаксический способ обеспечения этих инструкций. С этой точки зрения, различные языки программирования могут иметь различную грамматику или различные словари. Каждый язык может рассматривать точку с запятой по-своему или требовать заглавных букв в написании, хотя, по большому счету, в основе всех языков один и тот же принцип. Но реальность программирования гораздо сложнее. Программирование сегодняЭто странно, но большинство действительно “глобальных” идей в компьютерном программировании были разработаны еще в 1950-х и 60-х годах. С тех пор появилось много новых языков, но ни один из них не реализует действительно нового подхода к логике и вычислениям. Разработка новых языков программирования в течение последних нескольких десятилетий была основана на опыте разработчиков. Это означает, что появился код, который стало проще писать (движущая сила Ruby) и проще читать (Python), и делать определенные типы логических структур и способы решения проблем более интуитивными. Некоторые языки были разработаны для решения конкретных проблем в программировании (например PHP и SASS), чтобы управлять определенными типами систем (), или для работы в определенной среде или на определенной платформе (Java и JavaScript). Некоторые языки были разработаны специально для того, чтобы помочь новичкам научиться программировать (классическими примерами являются BASIC и Scratch). С тех пор, как теории и практики вокруг дизайна языка вылились (в основном) в широко признанную ортодоксию, большая часть новой и интересной работы в развитии практики программирования в настоящее время сосредоточена вокруг системной архитектуры. Относительно недавнее развитие включает в себя такое понятие, как SOA (Service Oriented Architecture- сервисо-ориентированная архитектура ) и MVC (Model-View-Controller), а также фреймворки, такие как , позволяющие программистам легко работать в рамках этих парадигм. Список языков программированияПополняющийся список популярных языков программирования, разметок и протоколов. Ссылки на описание каждого из них: Кодировка ASCII
ASP / ASP.NET
AutoLISP
Awk
BASH
Common Lisp
C
C++
C#
CSS / CSS3
Emacs Lisp
F#
FORTAN
FORTH
Haskell
HTML
IDL
INTERCAL
Java
Javascript
Ksh
Linux Programming
Logo
ML
MPI
Сетевое программирование с интернет-сокетамиObjective-C
OCaml
Разработка операционной системы
Perl
PROLOG
Pure Data
Python
Ruby on Rails
SAS
Scala
Scheme
Scratch
Simula
SMIL
SQL
Stata
Swift
S-PLUS
UNIX Programming
XML
Урок подготовил: Акулов Иван Если вы нашли опечатку - выделите ее и нажмите Ctrl + Enter! Для связи с нами вы можете использовать . |
Читайте: |
---|
Популярное:
Мобильные устройства изнутри |
Новое
- Загружаем виртуальную машину с флешки программой Virtual Machine USB Boot Виртуальная ос на флешке
- Чем отличается pci express 2
- Основная настройка Netis WF2780
- Поиск музыки по звуку онлайн
- Как откатить версию IOS на iPhone, iPad
- Как сделать яндекс стартовой страницей
- Фитнес-браслеты для Windows Phone
- Подключаем ноутбук к телевизору Настройка подключения пк к ноутбуку
- Что делать если клавиатура ноутбука не работает
- Как свернуть окно без помощи мышки