войти зарегистрироваться

Intel

Intel
хабраиндекс
225,71

Параллельное программирование в черном ящике

Около двух месяцев назад состоялся первый экспериментальный русскоязычный онлайн-семинар от Intel "Intel Parallel Studio workflow". На этом семинаре была сделана попытка показать, что существуют такие волшебные инструменты, которые помогут реализовать распараллеливание и оптимизацию кода на языке Си++, даже если вы не имеете полного представления о принципах работы программы. Я знаю, что подобный подход часто критикуется. И очередное напоминание, что показанные на вебинаре действия являются некорректными, сподвигло меня на этот пост.



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

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



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

Я практик. И считаю, что уже давным-давно никто не знает, как работают реальные программы. И нет смысла говорить, понятна отлаживаемая или распараллеливаемая программа разработчику или нет. Она всегда непонятна, если мы говорим о промышленной разработке ПО. Противники «теории черного ящика» (первая группа) являются в основном представителями академических кругов, преподавателями или людьми, занимающихся решением узких задач, где важна крайняя эффективность параллельности. Например, численное программирование. Обычно они имеют дело с прототипами программ, которые что-то вычисляют, в которых они хорошо разбираются и знают, какие алгоритмы распараллеливания следует применять в каждом конкретном случае. Программы невелики, их можно прочитать или даже при необходимости переписать заново — на другом языке. Ошибка в том, что они пытаются масштабировать свой опыт на большие программные проекты.

Аналогия со второй группой (теоретики, или противники черного ящика). Человек с фонариком и лупой, который с интересом изучает красивый сундук, покрытый росписью и предлагает способы как сделать его еще более красивым и удобным в использовании.

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

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

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

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

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

комментарии (47)

  • Спасибо за статью, прочитать было интересно, но сложно написано мне кажется.
    Вот эсли бы визуализировать информацию!
  • Гы. То есть Вы сейчас написали: никто не понимает, как работают большие программы. Более того, никто не способен понять… А где ж тогда гарантии, что программы работают правильно? :)
    • А их нет и быть не может в принципе, кроме простейших случаев с отдельно выделенными задачами!
      • То есть, вполне есть шанс, что я завтра установлю, скажем, Photoshop, а он вместо рисования рисунков начнёт музыку проигрывать? :) Я имею в виду ошибочность на уровне основной функциональности программы, а не мелких багов в интерфейсах.
      • В интерфейсах пользователей.
    • Более того — а они и не работают правильно. В багтрекере любого более-менее большого проекта висят сотни (а то и тысячи!) незакрытых багов. Просто в большинстве своем на них напоролось мало людей и поэтому такая ситуация никого не шокирует. А то, на что напоролось много — быстренько фикситься хот-фиксами.
      • Эмс. Баги это другое. Баг — это не крупная архитектурная ошибка, а мелочь какая-нибудь: забыли переменную обнулить или вместо == = поставили. И т.д. Человек же пишет о том, что люди пишущие программы об общей архитектуре представления не имеют. Возникает тогда вопрос: а как они вообще эти программы пишут?

        И куда подевалось всеми расхваливаемое ООП? Куда подевались хорошо документированные интерфейсы и инварианты для модулей: мол ядро Linux'а — это то, что умеет делать fork, fork работает должен порождать процесс так-то и так-то, а детали реализации ядра Linux уже никому не нужны. Неужели в больших люди проектах не производят декомпозицию на модули?
  • Блин, я ненавижу эти слова — «давным-давно никто не знает, как работают реальные программы». Это просто ппц.
    • Хм… А вы можете расписать как работает Ваша (или хоть какая) программа от интерфейса, до его обработчиков, алгоритмов обработки, вызовов функций библиотек, работу этих функций, функционал ядра операционки, драйверов, обрабатывающих запросы ядра, и конкретных железок, выполняющих ввод\вывод на устройства, в которых их прошивка осуществляет конечные действия (зажигает пиксели, передает байты в сеть)?

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

      Так какое у Вас есть право сказать «я полность понимаю как работает моя программа»?
      • Это бред. Программист может и должен понимать свою программу до мест, где она контачит с чужими вещами — операционной системой, сетью (подразумевается, что на другом конце чужая программа), железом.

        Когда каждый программист большого проекта знает только свой кусок, это неизбежно приведёт к тому, что куски начнут дублировать функционал (велосипедизм), конфликтовать друг с другом и т.п.
        • К сожалению, это реальность. Это я говорю как человек, работавший с несколькими крупными проектами возрастом более 10 лет.
          • Погодите. Я знаю, что бывают крупные проекты, о которых никто не знает, как оно работает. Я просто говорю, что существование таких проектов должно ограничиваться багфиксом. Пытаться добавить в них параллелизм методом чёрного ящика (т.е. не разбираясь в тонкостях внутренних механизмов) — бред. Не получится ничего. И никакие инструменты не помогут.
            • Я согласен, что бред. Но куда деваться, если сказали НАДО? Можно уволиться, но кому-то все равно придется это делать.
              • Сказали НАДО что? Взять и распараллелить отдельный образчик bloatware для достижения N% прироста производительности на многоядерной железке? Тут есть два выхода: отрабатывать зарплату (ну т.е. покупать кучи красивых инструментов, помогающих вытащить еще 1% скорости за счёт десятка новых багов) или переписывать всё по человечески. Мало ли что начальству надо? Может в следущий раз ему надо будет посмотреть, как я лечу из окна, не прыгать же мне?
      • Вы кажется подменяете одно понятие другим. Существует такая вещь, как модульность. И если вы параллелите модуль A, который вы разрабатываете, то вам не нужно знать более низкоуровневые модули B и C. Вы же не считаете, что если вы параллелите математический пакет, то вам нужно параллелить ядро операционки. При этом свой модуль вы должны понимать полностью.

        Сама ваша статья очень интересная, поставил ей и вам плюсы, но при этом мне кажется, что вы путаете кислое с красным, когда аргументируете ваши соображения.
        • И если вы параллелите модуль A, который вы разрабатываете, то вам не нужно знать более низкоуровневые модули B и C.

          В идеальной программе – да. В реальной — нет. Устройство низкоуровневых модулей B и C может не рассчитано на параллельные вызовы. Достаточно наличие одной глобальной (общей) переменной в этих модулях и мы уже имеем дело с состоянием гонки.
    • ППЦ… но такова реальность :(
      • Поверте, в каждом успешном проете есть люди, которые очень хорошо понимают структуру того, что делается. И если вы этого не понимаете, то это говорит о том, что вы скорее всего обычный разработчик, который выполняет задания более квалифицированного сотрудника, который как раз в этом разбирается.
        • Струтура того что делается и то как это делает есть разные вещи!
        • > в каждом успешном проете есть люди

          Речь идет не только об успешных проектах
    • Но так оно и есть. И по меркам истории компьютеров именно давно. Еще Эдсгер Дейкстра писал о кризисе в программировании и что программы стали крайне сложными и недетерминированными. Например, в статье «Смиренный программист» 1972 года он пишет:

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

      Так что вполне себе «давным-давно никто не знает, как работают реальные программы» :)
      • Не так, IMHO. Давным-двано программы не работают в рамках детерминированной последовательной модели. Но это не означает, что «никто не знает». Существуют же модели, позволяющие описывать поведение прерываемых, параллельных процессов. И позволяющие добиваться вполне определённых свойств от системы: сети Петри, темпоральная логика, всё такое прочее. Да, к простой, последовательной машине Тьюринга это не сводится, ну и что? Сводится зато к другой машине с другими, но тоже с понятными свойствами. Надо просто немного think different.
        • Я думаю, я еще сделаю не один пост и мы не раз продолжим спор в этом ключе. :) Вы относитесь ко второй группе (теоретиков). А я скорее себя ставлю ближе к первой группе (практиков и реалистов). Это не хорошо и не плохо, просто у нас разная картина мира. :) Когда я услышал про модели описания параллельных процессов и сети петри, я был готов поспорить, что Вы работаете или как-то связаны с ИПС/ИММ/xxx РАН. Посмотрел профиль – и действительно ИММ УрО РАН. ;))) Только боже упаси не подумайте, что я не считаюсь с теоретическими аспектами. Только на практике это может выглядеть так. Приходит в компанию, занимающуюся аутсорсом, очередной проект, который нужно развивать. И НИКТО не знает, что там. И никакие модели тут не помогут. :)
  • Распараллеливать чёрный ящик — крайне неблагодарное занятие. Ни один дебаггер вам не сможет потом помочь отлаживать race conditions и случайные deadlock'и.

    /me сторонник выкидывания мегабайтов старого трудноподдерживаемого кода и переписывания заново. Разумеется, если в этом действительно есть необходимость (не трогай работающую систему, да).
    • Вы когда-нибудь живого заказчика видели?
      • Нет, я их придумываю.

        Вам не нравится, что я люблю писать с нуля? :)

        У меня таких примеров тьма. Вот был заказчик, который хотел к битриксу прикрутить мааленький модуль. Сам битрикс в той ситуации заботился лишь за генерацию меню. Клиент был послан нафиг. Ну т.е. ему объяснили, что написать своё с помощью более другого фреймворка (фреймворк битрикс или cms — науке не известно. Известно только, что bloatware) будет стоить дешевле и закончится быстрее. Угадайте, что выбрал заказчик?

        Вариант, когда меня берут в фирму поддерживать старый дремучий проект, в котором я буду заниматься маааленьким модулем и фиксом накопившихся за 100 лет багов, на которых взорвался мозг у нескольких поколений программистов, я рассматривать не буду. С такими ситуациями не знаком (и не познакомлюсь).
        • Тем не менее вы представлете (гипотетически) такой проект, так ведь?
          • Да, такие проекты есть (даже не гипотетически). Только я писал уже выше,
            habrahabr.ru/company/intel/blog/78350/#comment_2290463
            • Ага, я понял. Просто хотел сказать, что всякое бывает. И теоретически иногда имеет смысл разбираться с кучей чужого кода. Я сам сторонник «переписывания», (даже если код — мой :). К сожалению, это не всегда возможно…
              • Да, я не исключаю возможности разбирательства в чужом коде. Я исключаю возможность наворотить реальных оптимизаций без внесения сложнонаходимых багов и при этом не разбираться в коде.
                • хорошая формулировка!
    • Вроде в валгринде есть такая штука как отслеживание гонок и дедлоков, но мне как то не приходилось с его помощью этим заниматься. А вообще, конечно, нужно изначально это планировать параллельность.
      • Не допускать проблему проще, чем потом её решать, это очень старое правило. В случае чёрного ящика вариантов особенно нету. Есть хороший (третий вариант) — уволиться (крамола, да). Что бы я и сделал в подобной ситуации.
      • Не так все плохо. Появляются соответствующие инструменты. И они уже умеют очень многое. Пожалуй, лучшим универсальным инструментом сейчас в этой области является динамический анализатор Intel Parallel Inspector. Развиваются альтернативные подходы, основанные на статическом анализе. Для OpenMP программ: Intel “Parallel Lint” и VivaMP. Для POSIX Threads можно взять PC-Lint.
        • Пеарстры! Пеарстры!
  • Что-то воды многовато. Как показывает практика, то большенство программистов даже не могут разобраться, в чем собственно заключается параллельность-асинхронность. Вот хороший цикл статей и обсуждений на эту тему параллельного программирования.
    Инициативы Интела понятны, им же нужно оправдать выпуск многоядерных процов, поскольку наращивать частоту они уже не могут. А переходить на немейстримовые языки, которые хорошо параллелятся никто не спешит. Вот они решили сами вбросить, но пока их затея выглядет фантастической.
    • По сути вы правы, но откуда негативная коннотация? Да, частоту поднимать становится все сложнее. Житкий азот дорожает на глазах :). Многоядерные процессоры — неплохой выход. Это даже обсуждать странно, ведь если бы кто-то мог сделать 10Ггц процессор — он бы его уже сделал.

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

      А насчет «решили сами вбросить» — я немного не понял.
      • Разговор о параллельном программировании ведется очень давно и языки существуют давно. Но проблемы то не решается. Пока все тянут. Но скоро выхода не останется. Сейчас стандарт 2 ядра, через 2 года будет 4, и чем дальше тем быстрее будут наращиватся ядра.

        Интел просто подходит только со своей стороны. Но пока это выглядет утопично. И для черных ящиков поднять производительность линейно все одно не смогут. Поэтому выход будет один — переписать, это трудно признавать, но это так. А вот если переписывать, то зачем брать С++, если есть более удобные языки для распараллеливания.

        >Почему не спешать параллелить?
        В интерпрайзе все инертно и никто никуда не торопится(а это основной рынок). Ждут-надеются на еще один усовершатор от Интела. Но все одно его эффективность будет во много меньше, чем код написанный с учетом ассинхронности на языке типа Эрланга.
        + не Интелом единым
        • Насколько мне известно, даже если программа пишется изначально многопоточной, то рост производительности от количества ядер не линейный. И чем больше ядер, тем больше пологий будет график.
        • Начинаю понимать ;)

          Тут ситуация такая: мы (ИНтел) пытаемся работать в нескольких направлениях. Если говорить о «более удобных» языках, то по возможности мы контактируем с разработчиками, участвуем в выработке стандартов и т.п.

          Да, я слышал множетсво комментариев в духе «вы большие, напишите параллельный питон или C#, что вам стоит?». К сожалению, это выглядит утопично. Нельзя сделать сразу все и всем. С этой точки зрения политика разумного вмешательства (или невмешательства, — это уж как удобнее) выглядит логично.

          С++ — отдельная тема. Это та область, которая близка к enterprise рынку, как вы правильно заметили. Но в то же время эта та область, в которой у интел есть опыт. Поэтому я с трудом представляю что в одном из инструментов Интел не будет поддержки C++.

          А еще я очень надеюсь, что когда-нибудь появится поддержка других языков :))))
      • >> Какие языки использовать для написания софта под многоядерные процессоры? Да любые!
        В принципе, вы правы. Но писать многопоточную программу на java и на Erlang — это тоже самое, что сверлить буравчиком или дрелью. А если к примеру взять пролог (с правильным рантаймом), то там программисту не надо даже думать о многопоточности. Всё и так распаралелится. Другое дело что пролог хорош только для определённых задач.
  • Увы, но не понял о чем пост. Рискну предположить, что он был о том, что есть инструменты, которые автоматически распаралелят старый код. И о том, какие категории людей как к этому относятся.

    Можно его резюмировать в 2-3 предложения?
    • «Мы интел, не забывайте о нас, люди. Особенно в такое жуткое для нас время, когда необходимость в x86 находится под таким большим вопросом. Мы наклепали для вас кучу тулзей, позволяющие запускать ваш код на фортране и коболе (ну ладно, на c++ тоже) на современных, многоядерных мало кому нужных монстрах!»

      Пеар, в общем.
      • На всякий случай обращу внимание, что я не работаю в компании Intel! И пиарить Intel мне смысла нет. :))
        • Каким образом вы тогда пишете в «Блог компании Intel Corporation»?
          • Да очень просто — у Андрея весьма солидный опыт в области параллельного программирования. Вот я его попросил написать несколько заметок в наш блог. Кстати, если есть желание присоединиться — пишите мне лично, обсудим ;)
Только авторизованные пользователи могут оставлять комментарии. Авторизуйтесь, пожалуйста.