Русский
Русский
English
Статистика
Реклама

Параллельные вычисления

Перевод Суперкомпьютеры и клеточные мембраны 2

28.04.2021 10:12:44 | Автор: admin

Предыдущая часть

С самодельным параллельным суперкомпьютером в рюкзаке Клаус Шультен терпеливо ждал в чикагском аэропорту О'Хара, надеясь, что после прибытия из Германии ему не составит труда пройти таможню. Это было летом 1988 года, и Шультен собирался начать новую работу в Университете Иллинойса. В разгар холодной войны, когда напряженность между США и Советским Союзом достигла наивысшего пика, суперкомпьютеры вызывали у администрации Рейгана большой ужас. Хотя Рейган, находясь на своем посту, усилил гонку вооружений и все сопутствующие ей технологические достижения, он хотел, чтобы бурно развивающиеся разработки суперкомпьютеров не попали в руки Советов, которые могли бы создать более совершенное оружие.

Оглавление

  1. Пересматривая устоявшиеся подходы

  2. Предтечи молекулярной динамики

  3. Шультен-числодробитель

  4. Рискованный план

  5. Паяльник вместо экзамена

  6. Транспортировка суперкомпьютера во время холодной войны

  7. Невзгоды теоретической биологии

  8. В поисках сотрудников

  9. Бунт аспирантов

  10. Отказ от платоновской информатики

  11. Ингредиенты NAMD

  12. Награда за декаду

  13. Вычислительный микроскоп достигает совершеннолетия

  14. NAMD в двадцать первом веке


В 1986 году правительство объявило о предполагаемой политике ограничения использования советскими учеными суперкомпьютеров, размещенных в университетах США. Все предельно прозрачно: никакого доступа для ученых из 20 стран коммунистического блока. Но реализация была не столь ясна. Университеты были возмущены этой политикой, беспокоясь о посягательствах на их академическую свободу и исследовательские инициативы, не понимая, как им стать исполнителями политики государственной безопасности.

Фотография самодельного суперкомпьютера, который Клаус Шультен перевозил в рюкзакеФотография самодельного суперкомпьютера, который Клаус Шультен перевозил в рюкзаке

Администрация Рейгана не только собиралась запретить советским ученым проводить моделирование на суперкомпьютерах, но и не хотела, чтобы советские ученые вообще находились рядом, опасаясь, что они могут научиться создавать свои собственные. Но в 1987 году два молодых студента-физика из Мюнхена взяли на себя именно такую миссию по созданию собственного параллельного суперкомпьютера, хотя ни один из них не имел формальной подготовки в этой области. Они не только воплотили свое стремление, но и стоимость их проекта составила около 60 000 долларов, что намного меньше, чем розничная цена Cray-2, популярного суперкомпьютера в конце 1980-х. Их научный руководитель, Клаус Шультен, решил рискнуть всеми грантовыми деньгами, хотя у него не было никаких гарантий, что проект ждет успех, и даже несмотря на то, что он не был экспертом в параллельных вычислениях.

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

Пересматривая устоявшиеся подходы

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

На курсах химии в колледже иногда, помимо учебников, требуются наборы для построения молекул. Студенты собирают молекулы из разноцветных атомов-шариков скрепляя их тонкими палочками. Результатом будет жесткая 3D-модель, которую можно повертеть в руках и рассмотреть со всех сторон. До 1977 года этот статический взгляд на биомолекулу все еще был распространен в некоторых научных кругах. Но постепенно начал происходить сдвиг в концептуальном понимании исследователей, после того, как 1977 год ознаменовался введением вычислительного метода, который прояснил движение атомов, составляющих биологические макромолекулы, что позволяло рассматривать их динамику. Этот сдвиг в сторону использования вычислительных методов для отражения такой динамики стал первым шагом в легитимации вычислительного микроскопа и дал стимул, побудивший Клауса Шультена создать свой собственный суперкомпьютер.

Предтечи молекулярной динамики

В 1968 году Мартин Карплюс был очень успешным химиком-теоретиком, работавшим в Гарварде, и он неожиданно понял, что пришло время вернуться к своей первой любви биологии.

Когда Карплюс был еще мальчиком, отец подарил ему микроскоп, что помогло воспитать в нем любовь к природе. Это пристрастие к природе только усилилось, когда Карплюс посетил лекцию в Бостонской публичной библиотеке под названием "Птицы и их идентификация в полевых условиях", что привлекло его к орнитологии. После, в средней школе, Карплюс был одним из победителей Westinghouse Science Talent Search со своим проектом по семейству чистиковых. Его любовь к биологии продолжалась и в студенческие годы в Гарварде, поскольку в своей автобиографической статье 2006 года он писал: "Я пришел к выводу, что для того, чтобы приблизиться к биологии на фундаментальном уровне (чтобы понять жизнь), необходимо иметь солидный опыт в химии, физике и математике, и поэтому я записался на программу по химии и физике." Однако его аспирантура по биологии не удалась, он перешел на химию и получил докторскую степень осенью 1953 года в Калтехе. (подробности можно найти в автобиографии "Шпинат на потолке: химик-теоретик возвращается в биологию")

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

Пребывание в Институте Вейцмана в 1969 году дало Карплюсу то, что он искал, и он вернулся в Гарвард с темами для изучения, а именно: происхождение связности гемоглобина, изучение ретинали в зрении и укладка белка.

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

С программой Брюса Гелина к середине 1970-х годов группа Карплюса подготовила почву для применения молекулярной динамики к биомолекулам. К моменту когда к группе присоединился Эндрю Маккаммон, код Гелина обрел законченную форму, реализуя уравнения Ньютона для расчета динамики или отдельных движений атомов белка.

Однако остальные коллеги не очень-то одобряли применение молекулярной динамики к биомолекулам. Как писал Карплюс в своей автобиографии 2006 года: "Когда я обсуждал свои планы с коллегами-химиками, они думали, что такие расчеты невозможны, учитывая сложность точного анализа нескольких атомных систем; коллеги-биологи считали, что даже если бы мы могли сделать такие расчеты, они были бы пустой тратой времени."

Но Карплюса это не разубедило. Он был воодушевлен двумя ответвлениями исследований более простых систем, которые сделали молекулярную динамику возможной для биомолекул. Первой была работа по расчету траекторий нескольких частиц для простых химических реакций, которую Карплюс изучал сам, когда занимался теоретической химией. Эти траекторные расчеты уходили корнями в 1930-е годы. Второе ответвление заключалось в изучении термодинамических свойств большого числа частиц - работа, начатая Берни Олдером и Томом Уэйнрайтом в конце 1950-х годов, когда они впервые применили молекулярную динамику к большой системе взаимодействующих частиц.

Карплюс знал не только о работах 1950-х годов по молекулярной динамике, но и о том, что в середине 1960-х и середине 1970-х годов другие исследователи использовали молекулярную динамику для моделирования жидкостей. Таким образом, с оглядкой на работы предшественников, Карплюс решил рискнуть сделать расчеты молекулярной динамики на биомолекуле, даже если его коллеги по биологии и химии не разделяли энтузиазма. Но преобладающее негативное отношение было не единственным, с чем столкнулись Карплюс и его сотрудники. Расчеты молекулярной динамики, которые они хотели провести, требовали серьезной вычислительной мощности. Карплюс утверждает, что в конце 1970-х годов было трудно получить компьютерное время для выполнения таких больших вычислений в Соединенных Штатах, поскольку большинство больших компьютеров предназначались исключительно для оборонных работ. Но когда возможность принять участие в семинаре в Европе пообещала доступ к компьютеру, Брюс Гелин и Эндрю Маккаммон принялись неустанно работать над подготовкой программы для запуска молекулярной динамики на небольшом белке.

Работа в CECAM (Center Europen Calcul Atomique et Molculaire) на большом компьютере прошла успешно, и троица, Маккаммон, Гелин и Карплюс, вскоре опубликовала свою статью по молекулярной динамике ингибитора трипсина поджелудочной железы крупного рогатого скота. Поскольку молекулярная динамика буквально показывает внутренние движения белка во времени, они смогли воспроизвести 9.2 пикосекунды времени жизни белка. В принципе, программа молекулярной динамики должна была бы воспроизвести время необходимое для развития биологического процесса. И хотя несколько пикосекунд могут показаться небольшим количеством времени для выяснения поведения белка, это послужит одной из направляющих сил в продвижении будущих исследователей к поиску более крупных и быстрых компьютеров. Ученые хотели продлить время моделирования расчета молекулярной динамики, то есть использовать вычислительный микроскоп для длительностей, выходящих за пределы пикосекундного диапазона.

Шультен-числодробитель

Шультен знал о работе Маккаммона, Гелина и Карплюса, потому что он заканчивал аспирантуру в Гарварде, где Карплюс был одним из его преподавателей, а Маккаммон и Гелин были сокурсниками, которых часто можно было встретить в коридоре. Статья 1977 года оказала определенное влияние на Шультена, который был обучен использовать теоретические и математические методы, такие как те, которые используются в химии и физике. "Я понял, что этот вычислительный подход, открывает новые двери для описания проблем, которые нельзя было сделать с чисто теоретическим подходом, который я использовал прежде."

Но принятие вычислительного метода вместо того, чтобы использовать исключительно чистую теорию, имело свои издержки, и вскоре он стал известен как "Шультен-числодробитель". "Я заплатил за это большую цену, потому что в основном на протяжении большей части моей карьеры люди считали меня глупым. Хотя я продолжал публиковать статьи, ориентированные на математику, для каждой статьи, ориентированной на вычисления, мне приходилось выкупать себя десятью теоретическими работами, и я не мог этого сделать." Шультен был не единственным в этой истории, кто был очернен своими коллегами за то, что отошел от чисто теоретических исследований.

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

Несмотря на многочисленные трудности, с которыми пришлось столкнуться Шультену, он был полон решимости использовать молекулярную динамику в своей работе; он был уверен, что это приведет его к новым открытиям, которые будут ценны для науки. "Моя любовь к научным открытиям, заставила меня заняться грязными вычислениями."

Рискованный план

Шультен хотел досконально разобраться в фотосинтезе, при котором солнечный свет превращается в биохимически пригодную энергию. Но важной макромолекулой в этом процессе является большой белок, который находится внутри мембраны. Имитировать белок сам по себе и пренебрегать мембраной и жидкостью, которая его окружает, было не желательно, потому что такая изоляция не является естественной средой для белка. Этот белок состоит примерно из 12 000 атомов, а мембрана и вода, окружающие его в естественной среде, добавляют еще 100 000. В конце 1980-х годов ни один суперкомпьютер даже близко не был способен справиться с этой задачей. Таким образом, Шультен решил сосредоточиться на понимании и моделировании только части мембраны в воде, когда выпала возможность выполнить расчет на Cray-XMP, но это позволило воспроизвести процессы всего в несколько пикосекунд, что натолкнуло на мысль: нужен свой суперкомпьютер на котором можно гонять расчеты год или больше, чтобы действительно понять механизм.

В то время как Шультен, преподававший физику в Мюнхенском техническом университете, задавался вопросом, как завести себе суперкомпьютер, молодой студент того же университета задавался вопросом, как получить возможность быстрый компьютер построить. На самом деле, теоретически, Гельмут Грубмюллер знал, как сделать компьютер быстрее, но ему было интересно, сможет ли он заставить кого-то другого оплатить это. При поступлении в Мюнхенский университет в 1985 году, двадцатилетний Грубмюллер осознал, как выбор специальности определил его цели: "Когда я начал заниматься физикой, я быстро понял, что для того, чтобы узнать больше о том, как работает природа, может потребоваться мощная вычислительная машина. В конечном счете, именно поэтому я был так очарован компьютерами; вы могли делать вычисления, которые иначе не осилить."

Во втором или третьем семестре он спаял многопроцессорный компьютер, который будет намного быстрее, чем то, что было доступно обычным студентам в те дни. Хотя технически это был параллельный компьютер, Грубмюллер просто назвал его мультипроцессором. Это была середина 1980-х, и не было никакой Всемирной паутины, чтобы проконсультироваться по техническим вопросам. Вместо этого он читал любые книги о микропроцессорах, какие только мог найти, и разговаривал по телефону с представителями компаний о технических характеристиках продаваемых ими деталей. В качестве наиболее важных для продвижения вперед источников информации для него были технические спецификации чипов, например, из линейки Motorola 68 000, которые он использовал в качестве процессора. Это увлечение быстро опустошило бюджет студента.

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

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

Одним из таких людей был Гельмут Геллер, который, как впоследствии узнал Шультен, пользовался некоторой славой в университете. Еще в старших классах Геллер начал сам изучать компьютеры. Он был счастливым обладателем одного из первых персональных компьютеров, PET 2001, представленный Commodore в конце 1970-х. Там было всего 8 килобайт оперативной памяти и кассета для архивирования данных. "Я начал с изучения BASIC с отладкой программ на этой машине. Потом же, начал писать машинный ассемблерный код", вспоминает Геллер. У него в родном городе было несколько друзей, которые тоже интересовались компьютерами и учили друг друга.

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

Клаус Шультен, Гельмут Грубмюллер, Гельмут Геллер и одна из плат самодельного суперкомпьютера,1988.Клаус Шультен, Гельмут Грубмюллер, Гельмут Геллер и одна из плат самодельного суперкомпьютера,1988.

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

Геллер сделал на компьютере сложный фильм про фракталы для этого задания. "Он показал нам, как он модифицировал компьютер, чтобы провести этот расчет. Даже сегодня я не в состоянии объяснить, что он на самом деле сделал." Наблюдение за тем, как Геллер играючи управляется с компьютером, действительно произвело впечатление на профессора. Шультен с удовольствием пригласил Геллера присоединиться к группе.

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

Паяльник вместо экзамена

Геллер и Грубмюллер, однако, составили отличную команду, и то, что они пытались сделать, было немалым подвигом. Им нужно было не только построить суперкомпьютер, но и написать программное обеспечение для параллельной работы на нем. "У нас с Гельмутом Грубмюллером были очень похожие, но в то же время комплиментарные компьютерные знания. Он больше занимался аппаратным обеспечением, а я программным.", вспоминает Геллер. Однако они разрабатывали и аппаратное, и программное обеспечение вместе, консультируясь друг с другом на каждом шагу.

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

В конечном итоге компьютер был собран и назван T60. За основу использовался кластер процессоров, известных как транспьютеры, потому что якобы из них можно было так же легко собрать схему, как из блоков Lego. В результате вышло 60 узлов: десять самодельных плат, по шесть транспьютеров на каждую. Все компоненты были спроектированы, спаяны и собраны вместе: транспьютеры, оперативная память, источник питания, вентиляторы (аэраторы), корпус, шины питания, печатные платы и крепления.

Поскольку пайка каждой из десяти печатных плат занимала много времени, к работе подключились другие члены исследовательской группы Шультена. Каждый участник получал детали и лист инструкций и начинал паять плату, что занимало по крайней мере около шести недель, а затем подписывал на ней свое имя. "Это действительно показывало исследовательскую личность студента", утверждает Шультен. "Работа, которую каждый в группе должен был проделать, действительно очень близко отражала то, как они на самом деле будут вести себя в команде и позже в науке." На самом деле Шультен считает, что вся эта пайка была даже лучше, чем традиционные результаты экзаменов, в определении того, какие кандидаты будут хорошими аспирантами, чтобы принять их в группу.

Геллер вспоминает о трудностях, с которыми столкнулась команда при написании кода для параллельной машины, кода, который они назвали EGO. "Я помню, что когда я впервые сделал параллельные вычисления, которые хорошо масштабировались, я был очень взволнован, но вскоре я обнаружил, что все результаты были неправильными! У меня была быстрая параллельная программа, дающая неправильные результаты." Найти причину этого было нелегко. Шультен купил кусок промышленного марципана, до которого Геллер был большой любитель, и время от времени отрезал ему ломтики, чтобы побудить его продолжать. После долгих добродушных насмешек со стороны других членов группы за его быстрые, но неправильные вычисления, Геллер в конце концов понял, что ему нужно правильно синхронизировать параллельные задачи, так как сначала он дал им слишком много свободы; решение заняло много дней и долгих вечеров работы.

Транспортировка суперкомпьютера во время холодной войны

Проект по созданию и программированию Т60 начался в конце 1987 года. На пол пути к его завершению Шультен получил новую работу в Соединенных Штатах, в Университете штата Иллинойс в Урбана-Шампейн. Вместо того чтобы отправить Т60 в Соединенные Штаты и неделями ждать, пока он прибудет, а затем пройдет таможню, Шультен решил просто пронести компьютер в рюкзаке.

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

Существовал специальный список ограничений и запрещенных материалов для экспорта в коммунистические страны, который был составлен под эгидой COCOM, комитета, созданного после Второй мировой войны для ограничения поставок оружия в Советский Союз. Список был единогласно согласован Соединенными Штатами, союзниками по НАТО и Японией. В 1984 году, после долгих ожесточенных споров между Соединенными Штатами и Западной Европой, особенно по поводу экспорта компьютеров, COCOM пересмотрела свой список товаров и в основном разрешила свободно экспортировать персональные, но не суперкомпьютеры.

Администрация Рейгана не только хотела ограничить бизнес, как внутренний, так и зарубежный, от экспорта суперкомпьютерных технологий в СССР, она также хотела держать советских ученых подальше от своих недавно созданных суперкомпьютерных центров. В 1985 году Национальный научный фонд выделил четырем университетам 200 миллионов долларов на открытие суперкомпьютерных центров в их кампусах. Этот шаг был признан необходимым и санкционирован Конгрессом, чтобы предоставить академическим исследователям доступ к суперкомпьютерам, которые обычно ограничивались оборонными работами, выполняемыми Пентагоном и Национальными лабораториями. Как сказал один из ключевых ученых, лоббировавших правительство США, использование стандартных компьютеров вместо упрятанных за бюрократическими препонами суперкомпьютеров "похоже на езду на лошади и возу, когда над головой летают самолеты". Но в 1986 году администрация Рейгана предложила запретить доступ к этим суперкомпьютерным центрам советским ученым. Таков был климат летом 1988 года, когда Клаус Шультен решил взять свой самодельный суперкомпьютер на трансатлантический рейс и пронести его через таможню в Чикаго.

Шультен знал, что из-за скорости обработки данных компьютер Т60 должен быть зарегистрирован, особенно при экспорте или импорте. Он подошел к таможеннику и показал ему суперкомпьютер.

Что это? спросил таможенник.

Это компьютер, ответил Шультен.

Зачем Вы мне его показываете?

Это очень мощный компьютер, и он должен быть зарегистрирован у вас.

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

Невзгоды теоретической биологии

Когда Шультен прибыл в Иллинойс, его ученики закончили собирать и программировать свой Т60. Программа, получившая название "EGO", была написана на языке OCCAM II языке, физическим воплощением которого, по сути, и являются транспьютеры. Точно так же, как создание T60 требовало больших усилий, написание параллельного кода было столь же трудной задачей. Одним из ключевых показателей в параллельном программировании является то, насколько хорошо масштабируется программное обеспечение; хорошее масштабирование (или параллелизуемость) означает, что время выполнения вычислений приближается к ускорению кратному количеству логических потоков. Например, сбор яблок человеком хорошо параллелизуется: по мере того, как все больше людей участвует в сборе, время выполнения работы уменьшается.

Мембранная структура, смоделированная на Т60 в течение двадцати месяцев, охватывала 24 000 атомов. Изображение из Heller et al., 1993.Мембранная структура, смоделированная на Т60 в течение двадцати месяцев, охватывала 24 000 атомов. Изображение из Heller et al., 1993.

Было очень важно, чтобы EGO хорошо масштабировалось, потому что расчет мембраны, который Шультен и его группа хотели запустить, был очень большой системой. На самом деле расчет занял двадцать месяцев безостановочных вычислений. Система, которую они изучали, мембрана из липидов, окруженная водой, состояла из 23 978 атомов. Для сравнения, число атомов в системе биомолекул, которую Маккаммон, Гелин и Карплюс изучали в 1977 году, было на два порядка меньше.

После таких невероятных усилий, приложенных к проблеме мембраны, можно представить себе удивление Шультена, когда их с Гельмутом Геллером и Михаэлем Шефером статья была отклонена в течение недели, хотя результаты хорошо согласовались с экспериментом. Статья содержала результаты теоретической биофизики. Шультен признает, что опубликовать теорию, связанную с биологией, очень сложно, особенно в журналах с высоким импакт-фактором. Он говорит, что даже сегодня у него больше шансов получить признание, если он объединится с экспериментаторами. В своей автобиографической статье 2006 года Мартин Карплюс суммирует препятствия, с которыми сталкиваются теоретики при публикации результатов, связанных с биологией: "Как и раньше, сегодня эта проблема все так же распространена, то есть, если теория согласуется с экспериментом, она не интересна, потому что результат уже известен, тогда как если кто-то делает прогноз, то он не может быть опубликован, потому что нет доказательств того, что прогноз верен."

Тайна отказа так и не была раскрыта. "Я до сих пор не знаю, почему ее отвергли", рассказывает Шультен. "Я был так взбешен, что, хотя я опубликовал много статей в этом журнале, я сказал им, что больше никогда не буду там публиковаться." Геллер, Шефер и Шультен в конце концов опубликовались в Journal of Physical Chemistry, и статья сейчас высоко цитируется.

Этот набег на молекулярную динамику такой гигантской для своего времени системы дал обоснование для использования параллельного компьютера в качестве вычислительного микроскопа. Было важно взять для анализа большой сегмент мембраны, потому что реальные клеточные мембраны непрерывны и не имеют края как такового. Другие типы обычных микроскопов не могли уловить некоторые критические особенности мембраны, которые проясняла молекулярная динамика. "Когда вы смотрите на мембрану в течении какого-то времени, то замечаете, что она вся текучая и движущаяся. Что довольно трудно рассмотреть с помощью микроскопов. А мы действительно видели с помощью компьютера сам процесс и могли провести сравнение с большим количеством экспериментов. Они измеряют некие усредненные характеристики, которые придавали нам убеждение в том, что то, что мы действительно видели с помощью компьютера, было правильной картиной." Успех вычислений только подогрел аппетит Шультена к изучению все больших и больших систем. Шультен не понимал, что его жажда массивных систем на параллельных машинах приведет к своего рода студенческому бунту и программному продукту под названием NAMD, который определит его карьеру.

В поисках сотрудников

В 1989 году Шультен основал группу теоретической биофизики [Theoretical Biophysics Group] (которая впоследствии стала группой теоретической и вычислительной биофизики) в Институте Бекмана Иллинойского университета. В 1990 году он получил двухлетний грант от Национального института здравоохранения, которого более или менее должно было хватить, чтобы центр заработал. К этому времени Шультен лучше разбирался в параллельных вычислениях, по сравнению с теми временами, когда он вложил все свои деньги в параллельную машину еще в Мюнхене; он понял, что может изучать массивные биомолекулы, используя преимущества параллельных машин. Уже существовали программные коды, некоторые даже в свободном доступе, которые занимались молекулярной динамикой, но Шультен понял, что его потребности намного превышают их возможности.

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

Во-первых, до 1991 года программированием молекулярной динамики в группе Шультена всегда занимались его студенты-физики. После того, как оба Гельмута написали EGO для самосборного компьютера, другой студент, Андреас Виндемут, написал код по молекулярной динамике для Connection Machine.

Как уже упоминалось ранее, в 1985 году в Соединенных Штатах были созданы четыре центра для предоставления академическим исследователям доступа к суперкомпьютерам. Четыре центра находились в Корнелле, Принстоне, Калифорнийском университете, Сан-Диего и Иллинойском университете, в Шампейн-Урбане, где находился Шультен. Иллинойский центр назывался NCSA, и группа Шультена имела доступ к Connection Machine, которая размещалась там. Видя программы для T60 и для Connection Machine Шультен понял, что ему нужны навыки разработки программного обеспечения в группе, чтобы убедиться, что программное обеспечение написано таким образом, чтобы в будущем оно было понятно и открыто для модификаций. Его студенты-физики просто не были обучены таким навыкам.

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

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

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

Бунт аспирантов

На самом деле Шультен воспринимает раннюю работу над T60 как приготовление почвы для NAMD это вкупе со студенческим бунтом, который произошел в начале 1990-х годов. В это время Шультен надеялся продолжить использовать коды молекулярной динамики, которые были разработаны для Connection Machine и Т60. Аспирант Боба Скила, Марк Нельсон, изучал код Connection Machine, а аспиранты Шультена, Билл Хамфри и Эндрю Далк, изучали код Т60. Все трое были непомерно раздражены своей работой. "Я бился головой об этот код в течение нескольких месяцев, рассказывает Нельсон, и никуда не продвигался. Комментариев не было, и все имена переменных были сокращениями немецких названий, что как-то мне не помогало."

Трое аспирантов, Нельсон, Хамфри и Далк, решили, что их задача будет проще, если они просто напишут новый код с нуля. Они тайно работали около месяца, пока не получили жизнеспособный код. Взяв на себя большой риск перед своими научными руководителями, они представили на собрании группы идею создать совершенно новый код и оставить в покое предыдущие реализации, которые было бы сложно поддерживать. "Они хотели написать все на C++ и боялись, что профессор пристрелит их за дерзкий отказ от работы с проверенным кодом." смеется Шультен. Однако на самом деле, он был в восторге от этой инициативы. "Так что я сам был очень взволнован, потому что увидел здесь ситуацию, которая была почти такой же, как у Гельмутов до них. Студенты осознавали риск и были готовы взять на себя ответственность."

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

Отказ от платоновской информатики

В начале 1980-х годов, будучи аспирантом в SUNY Stony Brook в Нью-Йорке, Кале начал работать над параллельным логическим программированием. В частности, он использовал язык Пролог для изучения искусственного интеллекта. "Так уж получилось, вспоминает Кале, что если вы осмотритесь в этой области сейчас, то увидите огромное количество людей, которые в середине 1980-х годов кодили на Прологе."

Санджай Кале, специалист по компьютерам в Университете Иллинойса с 1985 года.Санджай Кале, специалист по компьютерам в Университете Иллинойса с 1985 года.

Когда он получил работу в Университете Иллинойса, он продолжал работать над параллельным логическим программированием и получил должность в 1991 году. Пока он занимался этим более или менее "чистым" исследованием, основанным на компьютерных науках, он начал обдумывать применение своей работы. "Я занимался поиском на основе состояний, искусственным интеллектом в общем, и его распараллеливанием в частности, задачами а ля коммивояжера и т. д.", рассказывает Кале об этом периоде времени. "Но мои интересы начали смещаться в сторону: как мы можем применить это к задачам, которые есть у инженеров и ученых?"

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

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

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

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

К началу 1990-х годов Кале работал над прикладными проектами: Клауса Шультена по молекулярной динамике и еще одним по гидродинамике с сотрудником в области машиностроения. Что касается молекулярной динамики, то Кале изучал предыдущие коды, разработанные группой Шультена. Примерно в 1994 году аспиранты предложили начать все сначала. "Мы решили явно оформить его как программу", вспоминает Кале. "Сделать шаг назад и разработать его как программу, а не позволять ему быть органически выращенным." Этот формальный дизайн привел к прототипу NAMD. Название первоначально было акронимом "Not Another Molecular Dynamics", который придумал аспирант Билл Хампри, вдохновленный названием компилятора аналогичной природы; вскоре аббревиатура стала обозначать "NAnoscale Molecular Dynamics". Явное требование NAMD быть параллельным с самого начала будет иметь долгосрочные последствия с точки зрения успеха программного обеспечения.

Хотя Кале исполнил свое желание работать над приложениями, последнее десятилетие века сопутствовалось тяжелым трудом. Кале и его аспиранты разработали язык параллельного программирования, названный ими Charm++, который стал очень важным и ценным для успеха NAMD. Его собственные исследования в области компьютерных наук в течение десятилетия были сосредоточены на этом. "То, что мы предлагали, было параллельным C++ или параллельным объектно-ориентированным языком, который был по-своему новым и существенно отличался от того, как люди занимались параллельным программированием", рассказывает Кале. "Так что это был мой вызов заставить людей принять это."

Этому предприятию также характерно большое число поражений. У Кале остались стопки отклоненных грантовых предложений в качестве напоминания. Рецензенты говорили, что то, что он предлагал, либо невозможно, либо устарело. Его публикации тоже не всегда ценились: "Мы писали статьи, и я говорил: "Это продемонстрировано в молекулярной динамике". А люди отвечали: "Это просто параллельный C++. Многие люди делают параллельный C++". Они не обращали внимание на элемент новизны. И работы продолжали игнорироваться".

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

Ингредиенты NAMD

Многие факторы формировали направления в которых развивался NAMD в 1994 году, не последним из которых было то, что теперь он хорошо финансировался грантом NIH. Аспиранты настаивали на использовании языка С++, относительного новичка в области программирования. "C++ предложил хорошую комбинацию объектно-ориентированного языка, заявляет бывший студент Марк Нельсон, но мы все равно могли бы написать ключевые вычислительные части на C и получить необходимую скорость." Использование C++ в NAMD сделало его уникальным среди солверов молекулярной динамики того времени.

Поскольку NAMD должен был быть адаптирован для параллельных машин, разработчики должны были учитывать, как многие процессоры, составляющие параллельную машину, будут взаимодействовать друг с другом при выполнении вычислений молекулярной динамики. Кале и Аттила Гурсой, его аспирант, работали над средой Charm++ и кое-чем, что называлось message-driven execution. Хотя технические детали выходят за рамки этой статьи, достаточно сказать, что Charm++ использовал message-driven execution, чтобы эффективно позволить процессорам общаться друг с другом во время выполнения молекулярной динамики.

В то время как C++ и Charm++ были уникальными элементами для NAMD, параллельный дизайн с нуля был еще одной отличительной чертой. В начале 1990-х годов другие очень успешные коды молекулярной динамики, такие как Amber и CHARMM (который является гарвардским продуктом и не следует путать его с Charm++, который был разработан в Иллинойсе), приняли другую тактику, когда стало очевидно, что программное обеспечение должно быть разработано для параллельных компьютеров.

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

Санджай Кале приводит преимущества, которые дизайн с нуля давал NAMD: программное обеспечение хорошо масштабировалось и могло обрабатываться любыми новыми машинами, которые быстро появлялись на рынке. "Этот дизайн выдержал испытание временем и до сих пор актуален", размышляет Кале. "В значительной степени архитектура параллельной программы осталась прежней, хотя в то время мы работали на кластере HP, с восемью процессорами. А теперь мы работаем на 200 000 с лишним процессорах.

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

Награда за декаду

Почти через десять лет после того, как Кале начал свою одиссею в мир параллельных вычислений, он, наконец, был вознагражден. Каждый год проводится международная конференция Supercomputing. Премия Гордона Белла вручается ежегодно на конференции в знак признания достижений в области параллельных вычислений. И в 2002 году она была присуждена разработчикам NAMD.

Хотя Кале, возможно, работал в течение многих лет над такими прикладными проектами, как молекулярное моделирование и гидродинамика, он также занимался более или менее чистыми исследованиями в области компьютерных наук. Он считает, что премия Гордона Белла принесла его группе заслуженную славу. "На самом деле, я очень благодарен за это, отмечает Кале, потому что наши идеи в области информатики остались бы недооцененными. И было бы трудно добиться их признания, если бы не успех NAMD". Из-за своей репутации в NAMD у Кале теперь есть проекты в области моделирования погоды, вычислительной астрономии и вычислительной химии.

Вычислительный микроскоп достигает совершеннолетия

К этому времени вычислительный микроскоп стал более сложным. В 1977 году было проведено первое моделирование молекулярной динамики на небольшом белке в вакууме, которое отображало 9,2 пикосекунды. К 1996 году NAMD моделировал систему с 36 000 атомами, рецептор эстрогена с сегментом ДНК в соленой воде, в течение 50 пикосекунд. Расчет выполнялся в течение двух-трех дней на 8-процессорном кластере. В 2004 году для системы аквапорин-1, состоящей из 81 065 атомов, расчет проводился в течение 22,4 часов на параллельной машине с 128 процессорами и отобразил 5 наносекунд времени жизни системы.

Эти достижения утвердили вычислительный микроскоп для научного сообщества. "В прежние времена компьютерное моделирование не было таким точным", вспоминает Шультен. Поэтому было бы высокомерием просто сказать: 'Это вычислительный микроскоп', люди посмеялись бы над нами и сказали бы: 'У вас очень плохой микроскоп'.

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

Часто вычислительный микроскоп правильно предсказывал то, что наблюдал эксперимент; иногда он опережал эксперимент. Одним из таких случаев был пример использования NAMD для запуска моделирования "управляемой молекулярной динамики". В управляемой молекулярной динамике можно применить внешние силы к белку и отобразить его последующее поведение во времени. Анкириновый повтор это определенная последовательность аминокислот, и эта последовательность содержится в более чем 400 белках человека. В 2005 году Маркос Сотомайр, Дэвид П. Кори и Клаус Шультен изучали упругие свойства этих анкириновых повторов с помощью управляемой молекулярной динамики, в конечном счете, чтобы лучше понять слух и чувство равновесия; год спустя, в 2006 году, эксперимент подтвердил их результаты моделирования. В высоко цитируемой научной статье 2007 года Одномолекулярные эксперименты in Vitro и in Silico Сотомайр и Шультен утверждают, что эксперименты in silico "стали мощным инструментом, дополняющим и направляющим эксперименты in vitro". Термин 'in silico' относится к исследованию, выполненному с помощью компьютерного анализа. Обоснование вычислительного микроскопа как мощного инструмента только усиливалось по мере того, как этот эксперимент предвосхитил результаты эксперимента in vitro.

NAMD в двадцать первом веке

NAMD появился на свет в начале 1990-х годов, и семя его восходит к самодельному параллельному компьютеру, построенному в конце 1980-х годов, и программе EGO, которая была написана для этого конкретного суперкомпьютера. Шультен хотел управлять все большими и большими системами, и поэтому NAMD родился, а затем вырос, потому что он хорошо финансировался. Ключевым игроком, стоящим за успехом NAMD, является ведущий разработчик Джим Филлипс, бывший аспирант Шультена в 1990-х годах. Теперь Шультен называет Филлипса "отцом NAMD", поскольку Филлипс разрабатывал творческие решения для параллельного программного обеспечения почти два десятилетия.

Многие системы были смоделированы с помощью NAMD за его примерно двадцатилетнюю историю. Полный список выходит за рамки данной статьи, однако в приложении (оригинала) приведено несколько работ, описывающих молекулярную динамику ключевых белков, изученных группой Шультена в Бекмане. И каждая из этих публикаций была высоко цитируема. Некоторые из затронутых тем это исследования белка титина, который отвечает за пассивную эластичность мышц, и изучение того, как аквапорины работают, чтобы пропускать воду или глицерин через мембрану, но не пропускать протоны. Тот факт, что эти статьи имеют более сотни цитат каждая, доказывает их важность. Но чтобы завершить историю NAMD, сосредоточим внимания на том, чего достиг вычислительный микроскоп в своем исследовании вирусов, что освещает наследие NAMD за последние несколько лет.

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

Коллапс пустого капсида. Три снимка сверху взяты из моделирования всех атомов , а шесть внизу-из крупнозернистого моделирования.Коллапс пустого капсида. Три снимка сверху взяты из моделирования всех атомов , а шесть внизу-из крупнозернистого моделирования.

Кроме того, было обнаружено, что вирус птичьего гриппа H5N1 также обладает устойчивостью к Тамифлю. Используя NAMD, а также молекулярную динамику и управляемую молекулярную динамику, сотрудники Университета Иллинойса и Университета Юты объединили усилия, чтобы найти основу для этой лекарственной устойчивости. Их открытие, согласно их публикации 2010 года, "предполагает, как мутации нарушают связывание лекарств и как новые лекарства могут обойти механизмы устойчивости."

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

Вирусы это очень примитивные частицы, и многие из них состоят только из белковой оболочки, или капсида, окружающего нить ДНК или РНК. Для размножения вирус проникает в клетку-хозяина и захватывает ее механизмы, чтобы создать больше вирусных частиц. В то время как капсид играет роль защиты вируса, он также должен каким-то образом стать нестабильным и высвободить свои внутренние компоненты в клетку-хозяина для размножения. Распознавание движения белков, составляющих капсид во время такого высвобождения, является приоритетной целью, и исследование, проведенное в 2006 году, изучало динамику различных капсидов. Относительно новый метод крупнозернистая молекулярная динамика, позволял моделировать целые капсиды, которые до этого времени были недоступны. Ученые из Университета Иллинойса усовершенствовали метод крупнозернистой молекулярной динамики и использовали NAMD для иллюстрации стабильности капсида для нескольких вирусов. С помощью новой техники стало возможным моделировать капсиды размером более 10 нанометров и наблюдать переходы между стабильными и нестабильными структурами. Эта работа может дать полезную информацию для борьбы с вирусными заболеваниями.

Будущее для NAMD выглядит радужным. Цель Клауса Шультена понять биологическую организацию, саму суть того, что делает клетку живой, маячит на горизонте после сорока лет самоотверженности и творчества. "Так что теперь я могу потихоньку заняться тем, о чем мечтал, замечает Шультен о биологической организации, ближе к отставке. И другие люди следующие за мной могут использовать наработки сейчас и могут делать это намного лучше. И это, конечно, тоже делает меня счастливым." И вычислительный микроскоп продолжает прояснять все большие и большие системы. "Сегодня у нас есть симуляция на 20 миллионов атомов", хвастается Шультен. "И у нас есть симуляция, чтобы быть готовыми к следующему поколению компьютеров, которые потянут 100 миллионов атомов." Сочетание понимания и принятия риска, безусловно, окупилось с точки зрения научных открытий. От выяснения рецептора эстрогена, чтобы лучше понять рак молочной железы, до освещения вирусов, чтобы лучше бороться с болезнями, вычислительные проекты, ставшие возможными с помощью параллельных компьютеров, будут продолжать раздвигать границы. И до тех пор, пока смелые ученые идут на большой личный риск, пытаясь сделать то, что никогда не делалось раньше, и продолжают переосмысливать новые пути для того, чтобы компьютер действовал как научный инструмент, помогающий исследователям, будущее вычислительного микроскопа, кажется, наверняка принесет больше открытий.

Продолжение следует...

Подробнее..

Часть 2. MPI Учимся следить за процессами

23.03.2021 00:21:32 | Автор: admin

В этом цикле статей речь идет о параллельном программировании с использованием MPI.

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


Номера процессов и общее число процессов

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

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

int MPI_Comm_size(MPI_Comm comm, int* size)

Так что такое коммуникатор и зачем он собственно нужен? Коммуникатор это такой объект, который хранит в себе информацию о запущенных потоках, доступ к которым ему предоставлен. Роль коммуникатора в программе очень важна, так как большая часть работы с процессами связана именно через него, на то он и называется коммуникатором. В MPI существует глобальный коммуникатор который имеет доступ ко всем запущенным потокам, его название MPI_COMM_WORLD. Также мы можем создавать свои, локальные коммуникаторы для выполнения определенных задач на конкретных потоках, и это довольно мило.

Что такое коммуникатор разобрались, теперь было бы неплохо узнать на каком из процессов работает конкретный экземпляр программы. Для этого существует процедура MPI_Comm_size. Она принимает на вход аналогичные параметры, только вместо сохранения количества процессов она сохраняет по адресу номер конкретного процесса. Определена она вот так:

int MPI_comm_rank(MPI_Comm comm, int* rank)

То есть мы передаем ей коммуникатор в котором надо узнать номер процесса и собственно адрес куда его нужно записать.

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

#include <stdio.h>#include "mpi.h"int main(int argc, char **argv){int rank, size;MPI_Init(&argc, &argv);  MPI_Comm_size(MPI_COMM_WORLD, &size);MPI_Comm_rank(MPI_COMM_WORLD, &rank);  MPI_Finalize();  printf("Process: %d, size: %d\n", rank, size);return 0;}

Выход для 5 потоков будет следующим:

Process: 0, size: 5Process: 1, size: 5Process: 2, size: 5Process: 3, size: 5Process: 4, size: 5

Как видим каждый поток напечатал свой номер процесса и общее число запущенных процессов.

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

Работа Comm_size, Comm_rank на примере

Более полезным примером такого распараллеливания будет поиск квадратов чисел в заданном диапазоне. Далее идет небольшой пример программы которая это и делает.

#include <stdio.h>#include "mpi.h"int main(int argc, char **argv){const int MAX = 20;int rank, size;int n, ibeg, iend;MPI_Init(&argc, &argv);MPI_Comm_size(MPI_COMM_WORLD, &size);MPI_Comm_rank(MPI_COMM_WORLD, &rank);n = (MAX - 1) / size + 1;ibeg = rank * n + 1;iend = (rank + 1) * n;for(int i = ibeg; i <= ((iend > MAX) ? MAX : iend); i++){printf("Process: %d, %d^2=%d\n", rank, i, i*i);}MPI_Finalize();return 0;}

Выход для 5 потоков:

Process: 0, 1^2=1Process: 0, 2^2=4Process: 0, 3^2=9Process: 0, 4^2=16Process: 1, 5^2=25Process: 1, 6^2=36Process: 1, 7^2=49Process: 1, 8^2=64Process: 2, 9^2=81Process: 2, 10^2=100Process: 2, 11^2=121Process: 2, 12^2=144Process: 3, 13^2=169Process: 3, 14^2=196Process: 3, 15^2=225Process: 3, 16^2=256Process: 4, 17^2=289Process: 4, 18^2=324Process: 4, 19^2=361Process: 4, 20^2=400

Дабы не вставлять огромные участки с кодом я взял число MAX=20. Как видим зная номер процесса на котором исполняется конкретный экземпляр программы уже дает ощутимые возможности, но это далеко не все, ведь сложные задачи далеко не всегда так легко делятся на независимые участки с вычислениями.

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

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

Работа со временем

Кстати касательно времени. Чтобы работать со временем в MPI можно использовать как стандартные функции из библиотеки <time>, так и процедуры параллельной библиотеки.

double MPI_Wtime(void);double MPI_Wtick(void);

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

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

Вторая процедура как раз возвращает разрешение таймера конкретного процесса в секундах.

И на последок покажу как узнать имя физического процессора на котором выполняется программа. Для этого есть процедура MPI_Get_processor_name. Синтаксис и параметры вот такие:

int MPI_Get_Processor_name(char* name, int* len);

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

Резюмируем

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

Для закрепления полученных знаний предлагаю написать вам простую программу, которая узнает является ли число простым для чисел в заданном диапазоне от 1 до N. Это наглядно покажет вам как можно легко и просто распараллелить вычисления с помощью данной технологии и позволит отложить все полученные навыки в голове.

Всем приятного времени суток, хабравчане и те кто набрел на эту статью извне.

Подробнее..

Сравнение времени выполнения алгоритма на CPU и GPU

31.10.2020 16:04:39 | Автор: admin

Использование CUDA Runtime API для вычислений. Сравнение CPU и GPU вычислений.


В данной статье я решил провести сравнение выполнения алгоритма написанного на C++ на центральном и графическом процессоре(выполнение вычислений с помощью Nvidia CUDA Runtime API на поддерживаемом GPU Nvidia). CUDA API позволяет выполнение некоторых вычислений на графическом процессоре. Файл c++ использующий cuda, будет иметь расширение .cu.
Схема работы алгоритма приведена ниже.

Задача алгоритма состоит в том, что найти возможные числа X, при возведении которых в степень degree_of, будет получатся исходное число max_number. Сразу отмечу, что все числа которые будут передаваться GPU, будут хранится в массивах. Алгоритм, выполняемый каждым потоком, имеет приблизительно следующий вид:

intdegree_of=2;intdegree_of_max=Number_degree_of_max[0];//Массивхранящийзначениемаксимальнойстепеничислаintx=thread;//номервыполняемогопотокаintmax_number=INPUT[0];//Массивхранящийчисло,котороенеобходимополучитьintNumber=1;intDegree;boolBREAK=false;//Переменнаядлязавершенияwhilewhile(degree_of<=degree_of_max&&!BREAK){Number=1;for(inti=0;i<degree_of;i++){Number*=x;Degree=degree_of;}if(Number==max_number){OUT_NUMBER[thread]=X;//OUT_NUMBERМассивхранящийчислакоторыенеобходимовозвестивстепеньDegreeдляполученияисходногочислаOUT_DEGREE[thread]=Degree;//OUT_DEGREEМассивхранящийстепеньвкоторуюнужновозвестичислоXдляполученияисходногочисла}degree_of++;//Вслучаевыходазапредел:if(degree_of>degree_of_max||Number>max_number){BREAK=true;}}

Код для выполнения на CPU
#include <iostream>#include<vector>#include<string>//необходимо для getline#include<thread>#include<fstream>using namespace std;int Running_thread_counter = 0;void Upload_to_CPU(unsigned long long  *Number, unsigned long long  *Stepn, bool *Stop,unsigned long long  *INPUT, unsigned long long  *max, int THREAD);void Upload_to_CPU(unsigned long long  *Number, unsigned long long  *Stepn, bool *Stop,unsigned long long  *INPUT, unsigned long long  *max, int THREAD) {int thread = THREAD;Running_thread_counter++;unsigned long long  MAX_DEGREE_OF = max[0];int X = thread;unsigned long long  Calculated_number = 1;unsigned long long  DEGREE_OF = 2;unsigned long long   INP = INPUT[0];Stop[thread] = false;bool BREAK = false;if (X != 0 && X != 1) {while (!BREAK) {if (DEGREE_OF <= MAX_DEGREE_OF) {Calculated_number = 1;for (int counter = 0; counter < DEGREE_OF; counter++) {Calculated_number *= X;}if (Calculated_number == INP) {Stepn[thread] = DEGREE_OF;Number[thread] = X;Stop[thread] = true;BREAK = true;}DEGREE_OF++;}else { BREAK = true; }}}}void Parallelize_to_threads(unsigned long long  *Number, unsigned long long  *Stepn, bool *Stop,unsigned long long  *INPUT, unsigned long long  *max, int size);int main(){int size = 1000;unsigned long long  *Number = new unsigned long long[size], *Degree_of = new unsigned long long[size];unsigned long long  *Max_Degree_of = new unsigned long long[1];unsigned long long  *INPUT_NUMBER = new unsigned long long[1];Max_Degree_of[0] = 7900;INPUT_NUMBER[0] = 216 * 216 * 216;ifstream inp("input.txt");if (inp.is_open()) {string t;vector<unsigned long long>IN;while (getline(inp, t)) {IN.push_back(stol(t));}INPUT_NUMBER[0] = IN[0];//исходное числоMax_Degree_of[0] = IN[1];//значение максимальной степени}else {ofstream error("error.txt");if (error.is_open()) {error << "No file " << '"' << "input.txt" << '"' << endl;error << "Please , create a file" << '"' << "input.txt" << '"' << endl;error << "One read:input number" << endl;error << "Two read:input max stepen" << endl;error << "." << endl;error.close();INPUT_NUMBER[0] = 1;Max_Degree_of[0] = 1;}}//расскометрируйте следующий код , если хотите видеть исходные значения в окне консоли //cout << INPUT[0] << endl;bool *Elements_that_need_to_stop = new bool[size];Parallelize_to_threads(Number, Degree_of, Elements_that_need_to_stop, INPUT_NUMBER, Max_Degree_of, size);vector<unsigned long long>NUMBER, DEGREEOF;for (int i = 0; i < size; i++) {if (Elements_that_need_to_stop[i]) {if (Degree_of[i] < INPUT_NUMBER[0] && Number[i] < INPUT_NUMBER[0]) {//проверка на ошибки NUMBER.push_back(Number[i]);DEGREEOF.push_back(Degree_of[i]);}}}//расскометрируйте следующий код , если хотите вывести результаты в консоль//это может замедлить программу /*for (int f = 0; f < NUMBER.size(); f++) {cout << NUMBER[f] << "^" << DEGREEOF[f] << "=" << INPUT_NUMBER[0] << endl;}*/ofstream out("out.txt");if (out.is_open()) {for (int f = 0; f < NUMBER.size(); f++) {out << NUMBER[f] << "^" << DEGREEOF[f] << "=" << INPUT_NUMBER[0] << endl;}out.close();}}void Parallelize_to_threads(unsigned long long  *Number, unsigned long long  *Stepn, bool *Stop,unsigned long long  *INPUT, unsigned long long  *max, int size) {thread *T = new thread[size];Running_thread_counter = 0;for (int i = 0; i < size; i++) {T[i] = thread(Upload_to_CPU, Number, Stepn, Stop, INPUT, max, i);T[i].detach();}while (Running_thread_counter < size - 1);//дождаться завершения выполнения всех потоков }


Для работы алгоритма необходим текстовый файл с исходным числом и максимальной степенью.
Код для выполнения вычислений на GPU
//библиотеки cuda_runtime.h и device_launch_parameters.h//для работы с cyda#include "cuda_runtime.h"#include "device_launch_parameters.h"#include<vector>#include<string>//для getline#include <stdio.h>#include<fstream>using namespace std;__global__ void Upload_to_GPU(unsigned long long  *Number,unsigned long long  *Stepn, bool *Stop,unsigned long long  *INPUT,unsigned long long  *max) {int thread = threadIdx.x;unsigned long long  MAX_DEGREE_OF = max[0];    int X = thread;unsigned long long  Calculated_number = 1;unsigned long long  Current_degree_of_number = 2;    unsigned long long   Original_numberP = INPUT[0];Stop[thread] = false;bool BREAK = false;if (X!=0&&X!=1) {while (!BREAK) {if (Current_degree_of_number <= MAX_DEGREE_OF) {Calculated_number = 1;for (int counter = 0; counter < Current_degree_of_number; counter++) { Calculated_number*=X;}if (Calculated_number == Original_numberP) {Stepn[thread] = Current_degree_of_number;Number[thread] = X;Stop[thread] = true;BREAK = true;}Current_degree_of_number++;}else { BREAK = true; }}}}cudaError_t Configure_cuda(unsigned long long *Number, unsigned long long  *Stepn, bool *Stop,unsigned long long  *INPUT, unsigned long long  *max,unsigned int size);int main(){int size = 1000;    unsigned long long  *Number=new unsigned long long [size], *Degree_of=new unsigned long long [size];unsigned long long  *Max_degree_of = new unsigned long long [1];unsigned long long  *INPUT_NUMBER = new unsigned long long [1];   Max_degree_of[0] = 7900;ifstream inp("input.txt");if (inp.is_open()) {string text;vector<unsigned long long>IN;while (getline(inp, text)) {IN.push_back( stol(text));}INPUT_NUMBER[0] = IN[0];Max_degree_of[0] = IN[1];}else {ofstream error("error.txt");if (error.is_open()) {error<<"No file "<<'"'<<"input.txt"<<'"'<<endl;error<<"Please , create a file" << '"' << "input.txt" << '"' << endl;error << "One read:input number" << endl;error << "Two read:input max stepen" << endl;error << "." << endl;error.close();INPUT_NUMBER[0] = 1;Max_degree_of[0] = 1;}}bool *Elements_that_need_to_stop = new bool[size];    // Загрузка массивов в cudacudaError_t cudaStatus =  Configure_cuda(Number, Degree_of, Elements_that_need_to_stop, INPUT_NUMBER, Max_degree_of, size);    if (cudaStatus != cudaSuccess) {        fprintf(stderr, "addWithCuda failed!");        return 1;    }vector<unsigned long long>NUMBER, DEGREEOF;for (int i = 0; i < size; i++) {if (Elements_that_need_to_stop[i]) {NUMBER.push_back(Number[i]);//занести в вектор числоDEGREEOF.push_back(Degree_of[i]);//занести в вектор степень числа}}//раскоментируйте следующий код , чтобы вывести результаты в консоль/*for (int f = 0; f < NUMBER.size(); f++) {cout << NUMBER[f] << "^" << DEGREEOF[f] << "=" << INPUT_NUMBER[0] << endl;}*/ofstream out("out.txt");if (out.is_open()) {for (int f = 0; f < NUMBER.size(); f++) {out << NUMBER[f] << "^" << DEGREEOF[f] << "=" << INPUT_NUMBER[0] << endl;}out.close();}    //Очистить ресурсы связанные с устройством    cudaStatus = cudaDeviceReset();    if (cudaStatus != cudaSuccess) {        fprintf(stderr, "cudaDeviceReset failed!");        return 1;    }    return 0;}cudaError_t  Configure_cuda(unsigned long long  *Number, unsigned long long *Degree_of, bool *Stop,unsigned long long *INPUT, unsigned long long *max,unsigned int size) {unsigned long long *dev_Number = 0;unsigned long long *dev_Degree_of = 0;unsigned long long *dev_INPUT = 0;unsigned long long *dev_Max = 0;bool *dev_Elements_that_need_to_stop;cudaError_t cudaStatus;// УСТАНОВКА ИСПОЛЬЗУЕМОГО GPU cudaStatus = cudaSetDevice(0);if (cudaStatus != cudaSuccess) {fprintf(stderr, "cudaSetDevice failed!  Do you have a CUDA-capable GPU installed?");goto Error;}// РЕЗЕРВИРОВАНИЕ МЕСТА В ПАМЯТИ ПОД ДАННЕcudaStatus = cudaMalloc((void**)&dev_Number, size * sizeof(unsigned long long));if (cudaStatus != cudaSuccess) {fprintf(stderr, "cudaMalloc failed!dev_Number");goto Error;}cudaStatus = cudaMalloc((void**)&dev_Degree_of, size * sizeof(unsigned long long));if (cudaStatus != cudaSuccess) {fprintf(stderr, "cudaMalloc failed!dev_Degree_of");goto Error;}cudaStatus = cudaMalloc((void**)&dev_Max, size * sizeof(unsigned long long int));if (cudaStatus != cudaSuccess) {fprintf(stderr, "cudaMalloc failed!dev_Max");goto Error;}cudaStatus = cudaMalloc((void**)&dev_INPUT, size * sizeof(unsigned long long));if (cudaStatus != cudaSuccess) {fprintf(stderr, "cudaMalloc failed!dev_INPUT");goto Error;}cudaStatus = cudaMalloc((void**)&dev_Elements_that_need_to_stop, size * sizeof(bool));if (cudaStatus != cudaSuccess) {fprintf(stderr, "cudaMalloc failed!dev_Stop");goto Error;}// ПЕРЕМЕЩЕНИЕ ДАННХ В ПАМЯТЬ GPUcudaStatus = cudaMemcpy(dev_Max, max, size * sizeof(unsigned long long), cudaMemcpyHostToDevice);if (cudaStatus != cudaSuccess) {fprintf(stderr, "cudaMemcpy failed!");goto Error;}cudaStatus = cudaMemcpy(dev_INPUT, INPUT, size * sizeof(unsigned long long), cudaMemcpyHostToDevice);if (cudaStatus != cudaSuccess) {fprintf(stderr, "cudaMemcpy failed!");goto Error;}Upload_to_GPU<<<1, size>>>(dev_Number, dev_Degree_of, dev_Elements_that_need_to_stop, dev_INPUT, dev_Max);// Проверка сбоев ядраcudaStatus = cudaGetLastError();if (cudaStatus != cudaSuccess) {fprintf(stderr, "addKernel launch failed: %s\n", cudaGetErrorString(cudaStatus));goto Error;}// Ожидание завершения операций , выполняемых ядромcudaStatus = cudaDeviceSynchronize();if (cudaStatus != cudaSuccess) {fprintf(stderr, "cudaDeviceSynchronize returned error code %d after launching addKernel!\n", cudaStatus);goto Error;}// Перемещение данных из памяти GPU в системную памятьcudaStatus = cudaMemcpy(Number, dev_Number, size * sizeof(unsigned long long), cudaMemcpyDeviceToHost);if (cudaStatus != cudaSuccess) {fprintf(stderr, "cudaMemcpy failed!");goto Error;}cudaStatus = cudaMemcpy(Degree_of, dev_Degree_of, size * sizeof(unsigned long long), cudaMemcpyDeviceToHost);if (cudaStatus != cudaSuccess) {fprintf(stderr, "cudaMemcpy failed!");goto Error;}cudaStatus = cudaMemcpy(Stop, dev_Elements_that_need_to_stop, size * sizeof(bool), cudaMemcpyDeviceToHost);if (cudaStatus != cudaSuccess) {fprintf(stderr, "cudaMemcpy failed!");goto Error;}Error://Освобождение памяти GPU от данныхcudaFree(dev_INPUT);cudaFree(dev_Degree_of);cudaFree(dev_Max);cudaFree(dev_Elements_that_need_to_stop);cudaFree(dev_Number);return cudaStatus;}



Идентификатор
__global__  
в .cu файле указывает, что функция выполняется на уровне ядра GPU.
Для работы с cyda, перед вызовом функции, нужно зарезервировать память под массив и перенести элементы в память GPU. Это увеличивает объем кода, но позволяет разгрузить CPU, так как вычисления производятся на GPU.Поэтому ,cuda, дает как минимум возможность разгрузить процессор для выполнения других нагрузок, не использующих cuda.
В случае примера на cuda, задача процессора заключается лишь в загрузке инструкций на GPU и обработке результатов пришедших с GPU; В то время как в коде для CPU, процессор обрабатывает каждый поток. Стоит отметить, что cyda имеет ограничения по количеству запускаемых потоков, поэтому в обоих алгоритмах я взял одинаковое количество потоков, равное 1000. Также, в случае с CPU я использовал переменную
intRunning_thread_counter=0;

чтобы считать количество уже выполненных потоков и дожидаться, пока все потоки не выполнятся.
Тестируемая конфигурация
  • CPU :amd ryzen 5 1400(4core,8thread)
  • ОЗУ:8гбDDR4 2666
  • GPU:Nvidia rtx 2060

  • OS:windows 10 version 2004
  • Cuda:
    • Compute Capability 7.5
    • Threads per Multiprocessor 1024
    • CUDA 11.1.70

  • GPU-Z:version 2.35.0
  • Visual Studio 2017

Сведения о cyda были взяты из GPU-Z

Для тестирования алгоритма я использовал
следующий код на C#
usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;usingSystem.Diagnostics;usingSystem.IO;namespaceConsoleAppTESTSTEPEN_CPU_AND_GPU_{classProgram{staticstringUpload(Int64number,Int64degree_of){stringOUT="";string[]Chord_values=newstring[2];Int64Degree_of=degree_of;Int64Number=number;Chord_values[0]=Number.ToString();Chord_values[1]=Degree_of.ToString();File.WriteAllLines("input.txt",Chord_values);//файлвходныхданныхOUT+="inputnumber:"+Number.ToString()+"\n";OUT+="inputdegreeofnumber:"+Degree_of.ToString()+"\n";DateTimerunning_CPU_application=DateTime.Now;//записатьвремязапускапрограммыProcessproc=Process.Start("ConsoleApplication29.exe");//exeреализацияалгоритманаc++x64использующаяCPUдлявычисленийwhile(!proc.HasExited);//дождатсязавершенияпрограммыDateTimestop_CPU_application=DateTime.Now;//записатьвремяостановкипрограммыstring[]outs=File.ReadAllLines("out.txt");//получитьрезультатыFile.Delete("out.txt");OUT+="CPU:"+"\n";if(outs.Length>0){for(intj=0;j<outs.Length;j++){OUT+=outs[j]+"\n";}}else{OUT+="novalues"+"\n";}OUT+="running_CPU_application:"+running_CPU_application.ToString()+"\n";OUT+="stop_CPU_application:"+stop_CPU_application.ToString()+"\n";OUT+="GPU:"+"\n";//альтернативныедействиядляреализацииалгоритмаkorenXN.exex64использующегодлявычисленийGPUDateTimerunning_GPU_application=DateTime.Now;ProcessprocGPU=Process.Start("korenXN.exe");while(!procGPU.HasExited);DateTimestop_GPU_application=DateTime.Now;string[]outs2=File.ReadAllLines("out.txt");File.Delete("out.txt");if(outs2.Length>0){for(intj=0;j<outs2.Length;j++){OUT+=outs2[j]+"\n";}}else{OUT+="novalues"+"\n";}OUT+="running_GPU_application:"+running_GPU_application.ToString()+"\n";OUT+="stop_GPU_application:"+stop_GPU_application.ToString()+"\n";returnOUT;//возвратитьрезультат}staticvoidMain(){Int64start=36*36;//начальноезначениевходногочислаInt64degree_of_strat=500;//начальноезначениемаксимальнойстепениintsize=20-5;//количествоэлементоввмассивеInt64[]Number=newInt64[size];//массиввходныхчиселInt64[]Degree_of=newInt64[size];//массивмаксимальныхстепенейstring[]outs=newstring[size];//масссиврезультатовfor(intn=0;n<size;n++){if(n%2==0){Number[n]=start*start;}else{Number[n]=start*degree_of_strat;Number[n]-=n+n;}start+=36*36;Degree_of[n]=degree_of_strat;degree_of_strat+=1000;}for(intn=0;n<size;n++){outs[n]=Upload(Number[n],Degree_of[n]);Console.WriteLine(outs[n]);}System.IO.File.WriteAllLines("result.txt",outs);//записатьрезультатывфайлresult.txt}}}


, который создавал файл с исходными данными, затем последовательно запускал exe файлы алгоритмов использующих CPU или GPU и замерял время их работы, затем заносил это время и результаты работы алгоритмов в файл result.txt. Для замера загруженности процессора использовался диспетчер задач windows.
Результаты теста превидены в таблице:

Как видно из таблицы, время выполнения алгоритма на GPU немного больше, чем на CPU.
Однако, отмечу, что вовремя работы алгоритма использующего для вычислений GPU загрузка им CPU, в Диспетчере задач, не превышала 30%, в то время как алгоритм использующий для вычислений CPU, загружал его на 68-85%, что в свою очередь иногда приводило к замедлению других приложений. Также, ниже приведен график, показывающий различие во
времени выполнения (по оси Y)CPU и GPU в зависимости от входного числа(по оси X).
график


Далее я решил провести тестирование при процессоре нагруженном другими приложениями. Процессор был нагружен так, что запущенный в приложение тест, не занимал больше 55% ресурсов процессора. Результаты теста приведены ниже:

График


Как видно из таблицы, в случае с нагруженным CPU, выполнение вычислений на GPU, дает прирост производительности, так как загруженность процессора в 30% укладывается в лимит 55%, а в случае использования CPU для вычислений, его загрузка составляет 68-85% , что тормозит работу алгоритма, если CPU нагружен другими приложениями.

Поэтому, можно сделать вывод, что использование GPU для вычислений, не обязательно должно давать более быструю работу алгоритма, однако, оно способно разгрузить CPU, что может играть роль, если он нагружен другими приложениями.


Подробнее..

Научно-исследовательские инициативы JetBrains

03.03.2021 14:04:54 | Автор: admin
Develop with pleasure, The drive to develop об этом вы наверняка от нас слышали. Но наши интересы далеко не ограничиваются разработкой и созданием мощных инструментов для повышения продуктивности. Мы верим, что можем многое изменить и сделать мир лучше. Один из верных способов проведение исследований в области передовых технологий и образования. Совместно с ведущими научными учреждениями мира мы занимается прикладными исследованиями, способными влиять на жизни людей и двигать нас всех вперед.

Наши научные исследования объединены в рамках направления JetBrains Research.

Ниже мы представим исследовательские группы JetBrains Research и расскажем, чем они занимаются.

Наука сегодня для технологий будущего



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


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



Исследовательские группы



BioLabs


Сколько же всего мы по-прежнему не знаем о внутреннем устройстве человека: какие факторы приводят к генным мутациям, по каким индикаторам можно предсказывать будущие проблемы со здоровьем, как решить задачу полного секвенирования генома и многое другое. Биология как наука прошла огромный путь, однако ей предстоит еще немало.


Задача BioLabs раскрыть механизмы эпигенетической регуляции у людей и животных и понять, какое значение эти механизмы играют в процессах дифференцировки и старения клеток. Самым крупным является проект старения, реализуемый BioLabs совместно с Университетом Вашингтона в Сент-Луисе. Другие исследовательские проекты посвящены различным темам, включая новые алгоритмы анализа данных, эффективные инструменты обработки данных для секвенирования нового поколения (Next Generation Sequencing), масштабируемые конвейеры данных, подходы к визуализации и мета-анализу существующих баз данных с информацией о механизмах эпигенетической регуляции. BioLabs также отвечает за PubTrends новый сервис для анализа научных публикаций, позволяющий быстрее анализировать тренды и находить значимые работы. Такой сервис необходим, поскольку число работ, публикуемых каждый год, неуклонно растет, и уследить за всеми публикациями по выбранной теме практически невозможно.


Вернуться к списку исследовательских групп


Группа биоинформатики


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

Группа биоинформатики занимается разработкой эффективных вычислительных методов для решения важных проблем в области биологии и медицины. Группа базируется на кафедре компьютерных технологий Университета ИТМО. Группа активно взаимодействует с лабораторией Максима Артемова (Университет Вашингтона в Сент-Луисе). Проекты лаборатории охватывают широкий спектр тем от анализа данных метагеномного секвенирования до анализа экспрессии генов и метаболомики. Фундаментальные знания в области алгоритмов и компьютерных наук позволяют группе заниматься решением задач биологии, сводя их к известным вычислительным задачам и создавая инструменты визуализации и анализа данных для биологов.


Вернуться к списку исследовательских групп


Лаборатория нейробиологии и физиологии развития


Нейробиология и физиология развития прошли долгий путь и накопили фундаментальную базу исследований. И тем не менее многое в этой науке по-прежнему остается неизведанным. А ведь эти науки таят в себе огромный потенциал к пониманию человеческого мозга.
Задача лаборатории нейробиологии и физиологии развития разработать вычислительный фреймворк для создания динамических пространственных моделей структуры нервных тканей и динамики базовых стимулов. Проект Biological Cellular Neural Network Modeling (BCNNM) использует последовательности биохимических реакций для запуска сложных моделей нейронных сетей при формировании исходных стволовых клеток. Фреймворк можно использовать для in silico репликации экспериментов, проведенных in vitro, чтобы получать измерения с ключевых компонентов, а также выполнять предварительную вычислительную проверку новых гипотез.


Вернуться к списку исследовательских групп



Лаборатория прикладного машинного обучения и глубокого обучения
и
Лаборатория агентных систем и обучения с подкреплением


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


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


Вернуться к списку исследовательских групп


Исследовательская группа Paper-Analyzer


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


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


Вернуться к списку исследовательских групп


Лаборатория криптографии


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


Лаборатория криптографии занимается исследованиями современных задач в области криптографии и информационной безопасности. Она сотрудничает с COSIC исследовательской группой компьютерной безопасности и промышленной криптографии в Левене (Бельгия), Selmer Center в Университете Бергена (Норвегия) и INRIA (Франция). Исследования ведутся по различным направлениям: криптографические логические функции, симметричные шифры, легковесная криптография, технология блокчейна, квантовая криптография и информационная безопасность. Помимо публикации монографий и статей в ведущих журналах о криптографии, сотрудники лаборатории преподают криптографию в Новосибирском государственном университете и организуют NSUCRYPTO Международную студенческую олимпиаду по криптографии.


Вернуться к списку исследовательских групп


Группа HoTT и зависимых типов


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


Исследовательская группа занимается созданием Arend зависимо-типизированного языка и инструмента доказательства теорем, основанного на гомотопической теории типов. HTT является более продвинутым фреймворком, чем те, на которых основаны инструменты вроде Agda и Coq. Конечная цель создать онлайн-помощник для доказательства теорем, основанный на современной теории типов, который бы позволил формализовать определенные разделы математики.


Вернуться к списку исследовательских групп


Лаборатория методов ядерно-физических экспериментов


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


Лаборатория методов ядерно-физических экспериментов базируется в МФТИ. Основной интерес лаборатории методологии и ПО для решения задач в области физики элементарных частиц. На данный момент команда программистов лаборатории занимается разработкой нового поколения инструментов для получения данных (медленное управление, обработка сигналов) и анализа данных. Исследования лаборатории охватывают три сферы: физика элементарных частиц без ускорителя (эксперименты GERDA, Троицк ню-масс, KATRIN и IAXO), численное моделирование в физике элементарных частиц (эксперименты с ускорителем и без, атмосферное электричество, физика рентгеновского излучения) и разработка программного обеспечения для экспериментальной физики (системы получения и анализа данных, проекты по разработке инфраструктур, научные библиотеки для языка Kotlin). Огромное внимание уделяется и обучению: лаборатория старается дать молодым студентам возможность получить реальный опыт в физике и разработке.


Лаборатория методов ядерно-физических экспериментов


Вернуться к списку исследовательских групп


Лаборатория исследований процессов обучения


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


Задача лаборатории исследования процессов обучения разрабатывать мероприятия по продвижению предметов STEM среди старшеклассников и увеличению их шансов на успех при построении профессиональных карьер в областях STEM. Лаборатория занимается долгосрочным исследовательским проектом по выявлению главных индикаторов успеха учащихся в программировании и предметах STEM (наука, технологии, инженерия и математика). Мы ищем сочетание четырех возможных факторов: когнитивные навыки, некогнитивные характеристики (образовательные и профессиональные отношения, социальная среда), гендер и методологии обучения. Необходимо найти ответы на следующие вопросы:


  1. Кто идет в STEM и программирование?
  2. Какие факторы (когнитивные возможности, история семьи и т. д.) приводят человека к лучшим результатам и уменьшают вероятность забросить учебу?
  3. Существуют ли характерные установки (мотивация, вовлеченность и т.д.), способные пересилить первоначальные данные?
  4. Какие методологии обучения приносят успех, а какие повышают вероятность неудачи?

Вернуться к списку исследовательских групп


Лаборатория алгоритмов мобильных роботов


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


Лаборатория алгоритмов мобильных роботов объединяет исследования в области разработки эффективных алгоритмов для мобильных роботов. В лаборатории имеется единственный в России экземпляр Duckietown платформы и среды, позволяющих разрабатывать алгоритмы для мобильных роботов. В центре внимания лаборатории задача одновременной локализации и построения карты (SLAM). SLAM подразумевает составление и последующее поддержание карты неизвестной среды; при этом благодаря анализу данных с различных датчиков можно отслеживать местонахождение агента в среде. Сложность задачи SLAM связана с шумами, свойственными физическим датчикам, а также с необходимостью следить за изменениями в динамической среде. Кроме того, многие алгоритмы SLAM рассчитаны на недорогое оборудование, которое задает строгие требования к производительности. В 2019 году лаборатория роботов участвовала в третьих AI Driving Olympics соревнованиях роботов, управляющих беспилотным транспортом. Эти престижные соревнования считаются местом силы для развития знаний в сфере беспилотных автомобилей. Наша лаборатория заняла первое место во всех трех состязаниях. Примечательно, что это был первый прецедент победы алгоритма глубокого обучения на этих соревнованиях.


Исследователи лаборатории преподают множество курсов по дисциплинам STEM в университетах. Также они предлагают курсы по мобильной разработке для школьников и принимают студентов из MIT, приезжающих по программе MISTI.


Лаборатория алгоритмов мобильных роботов


Вернуться к списку исследовательских групп


Проблемы оптимизации в программной инженерии


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


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


Вернуться к списку исследовательских групп


Группа параметризованных алгоритмов


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


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


Вернуться к списку исследовательских групп


Лаборатория параллельных вычислений


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


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


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


Вернуться к списку исследовательских групп


Лаборатория киберфизических систем


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


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


Вернуться к списку исследовательских групп


Методы машинного обучения в области программной инженерии


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


Группа методов машинного обучения в области программной инженерии занимается разработкой и тестированием методов улучшения инструментов и процессов разработки путем применения анализа данных (включая машинное обучение) к данным из программных репозиториев. Совместно с командами нескольких продуктов JetBrains группа занимается интеграцией в продукты современных методов на основе данных. В данный момент группа работает над десятком исследовательских проектов на различные темы от поддержки библиотек сбора данных до генерации кода из описаний на естественном языке. Недавние результаты работы группы включают новый подход к рекомендации рефакторингов Move method, исследование нарушений лицензий в заимствованном коде на GitHub, современный подход к присуждению авторства исходного кода и метод построения векторных представлений стиля кода без явных признаков.


Вернуться к списку исследовательских групп


Лаборатория языковых инструментов


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


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


Вернуться к списку исследовательских групп


Лаборатория верификации и анализа программ (VorPAL)


Одним из главных направлений работы над инструментами JetBrains является повышение продуктивности при их использовании. И тот уровень, которого наши инструменты достигли сегодня, во многом заслуга тех исследований, которыми занимаются наши лаборатории.


В лаборатории верификации и анализа программ студенты, аспиранты и исследователи занимаются разработкой программных технологий, основанных на формальных методах, таких как верификация, статический анализ и методы трансформации программ. Эти методы помогают повысить продуктивность разработчиков при использовании ими автономных инструментов, расширений языков программирования и плагинов для IDE.
Существенная часть исследований посвящена изучению возможностей по расширению Kotlin. Мы верим, что Kotlin можно продолжать улучшать и расширять. Например, это могут быть макросы, liquid-типы, pattern matching, вариативные дженерики. Также в лаборатории занимаются исследованием применения
конколического тестирования в Kotlin, различных техник фаззинга компилятора и других областей.


Лаборатория верификации и анализа программ (VorPAL)


Вернуться к списку исследовательских групп


Лаборатория инструментов совместной работы


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


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


Вернуться к списку исследовательских групп



Если вы хотите присоединиться к какой-либо из групп, создать совместный проект или у вас есть общие вопросы, пишите нам по адресу info@research.jetbrains.org.


Благодарим Ольгу Андреевских за помощь в подготовке этой публикации.



Ваша команда JetBrains Research
The Drive to Develop
Подробнее..

Из песочницы Распараллеливаем код в R за пару минут

09.11.2020 20:17:29 | Автор: admin

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


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


Исходные данные:


a <- matrix(rnorm(500000, mean=0, sd=2), 100000, 50)

Функция:


sum.of.squares <- function(n) {  n_sq <- sapply(n, function(x) x^2)  sum(n_sq)}

Можно просто перебрать циклом строки, и к каждой из строк применить эту функцию, но это не самый рекомендуемый способ для R. Вычисления для каждой из строк будут выполняться последовательно, все расчёты будут идти на одном ядре. Такой код действительно не очень производителен. На всякий случай запишем такой вариант и замерим время его выполнения:


b <- vector()for(i in 1:dim(a)[1]) {  b[i] <- sum.of.squares(a[i,])}

Замеряем время выполнения:


b <- vector()start_time <- Sys.time()for(i in 1:dim(a)[1]) {  b[i] <- sum.of.squares(a[i,])}timediff <- difftime(Sys.time(), start_time)cat("Расчёт занял: ", timediff, units(timediff))

Получаем:


Расчёт занял:  4.474074 secs

Будем использовать это время как некоторую отправную точку для сравнения с другими способами.


Выполнение заданной операции над каждой из строк некоторого объекта можно записать в векторизованной форме. Для этого в R есть специальное семейство функций apply(). Для тех кто не знаком с ними, могу порекомендовать статьи по их использованию: 1, 2. Данные функции примечательны тем, что позволяют компактно описать однотипные действия без использования циклов. Даже в нашей функции расчёта суммы квадратов я для краткости использовал одну из таких функций sapply(), которая выполняет некоторое заданное действие для каждого из элементов поступающего на вход набора значений. В нашем случае вычисляет квадрат каждого из значений. Если же говорить про применение данной функции к матрице исходных данных, то с использованием функции apply() это можно переписать как:


b <- apply(a, 1, function(x) sum.of.squares(x))

Действительно, очень компактная запись. Но если замерить время её исполнения, то получим примерно то же, что и у цикла:


start_time <- Sys.time()b <- apply(a, 1, function(x) sum.of.squares(x))timediff <- difftime(Sys.time(),start_time)cat("Расчёт занял: ", timediff, units(timediff))

Результат:


Расчёт занял: 4.484046 secs

К слову, уже первый знак после запятой может от запуска к запуску немного меняться. Но суть ясна: это примерно тот же результат, что и с циклом.


Казалось бы, мы возвращаемся к исходному положению, что R считает всё в одном потоке, и от этого значительная часть ресурсов компьютера простаивает без дела. В некотором смысле так и есть: в данный момент функции семейства apply(), хотя потенциально их и можно распараллелить, выполняются последовательно. Но если рассмотреть ситуацию немного шире, то уже сейчас идёт работа, чтобы сделать их параллельными. Более того, уже сейчас эти функции из будущего можно загрузить и использовать вместо обычных функций семейства apply(). Помимо непосредственно функции apply() распараллеливаются также функции by(), eapply(), lapply(), Map(), .mapply(), mapply(), replicate(), sapply(), tapply(), vapply(). Со временем параллельные реализации этих функций заменят текущие, а пока что для их использования необходимо поставить специальный пакет future_apply:


install.packages("future.apply") 

Буквально несколько секунд и вот он установлен. После этого его надо подключить и указать, что расчёт пойдёт в многоядерном режиме:


library("future.apply")plan(multiprocess)

Есть различные параметры запуска. Например, поддерживается расчёт на распределённом кластере. Текущие настройки параллельного расчёта можно посмотреть используя команду future::plan(). Чтобы пользоваться возможностями параллельного расчёта, код основной программы менять практически никак не нужно, достаточно дописать к функциям apply приставку "future_". Получим:


b <- future_apply(a, 1, function(x) sum.of.squares(x))

Запустим с замером времени:


start_time <- Sys.time()b <- future_apply(a, 1, function(x) sum.of.squares(x))timediff <- difftime(Sys.time(),start_time)cat("Расчёт занял: ", timediff, units(timediff))

Получаем уже совсем другое время выполнения:


Расчёт занял:  1.283569 secs

В моём случае расчёт производился на Intel Core i7-8750H с 12 логическими ядрами. Полученное ускорение конечно не 12-кратное, но всё же довольно приличное.


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


Ну вот, собственно, и всё. Способ достаточно простой. Для меня, когда я про него узнал, это была просто находка. Справедливо ли утверждение, что нынешний R не поддерживает параллельные вычисления? Зависит от точки зрения на этот вопрос, от строгости его постановки. Но в некотором смысле можно считать, что всё-таки поддерживает.

Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru