OpenCL: Как заставить эту штуку работать

image

Очень многие, пробовавшие «на вкус» технологию использования графических ускорителей CUDA/OpenCL получили не слишком хорошие результаты. Да, тесты идут и простые примеры показывают впечатляющее ускорение, но вот когда дело доходит до реальных алгоритмов, хороший результат получить очень непросто.
Как же заставить эту технологию работать?
В данной статье я постарался обобщить свой полугодовой опыт бодания с технологией OpenCL под Mandriva linux и MacOS X 10.6 на задачах сложного поиска строковых данных для биоинформатики. OpenCL был выбран т. к. для Мака он является «родной» технологией (часть маков комплектуется видеокартами AMD и CUDA под ними недоступна даже теоретически), но предлагаемые рекомендации достаточно универсальны и подходят в том числе и для NVIDIA CUDA.

Итак, что необходимо, чтобы графический ускоритель заработал?


Параллельность кода


1. Нужно вспомнить, а для тех, кто не знал — изучить приемы рефакторинга кода. Если у вас нетиповой алгоритм, будьте готовы к тому, что его придется долго терзать, прежде чем удастся правильно распараллелить. В ходе этих терзаний результаты работы программы не должны меняться, потому без хорошего тестового примера к работе можно даже не приступать. Пример должен отрабатывать не слишком долго, т. к. запускать его придется часто, но не слишком быстро, — мы должны оценивать скорость его работы. Оптимально — секунд 20.
2. Массовая параллельность на ускорителе подразумевает, что на входе и на выходе алгоритма будут массивы данных, причем размерность этих массивов не может быть меньше, чем количество нитей параллельного алгоритма. Ускоряемый алгоритм обычно выглядит как цикл for (или несколько вложенных таких циклов) каждая итерация которого не зависит от результата предыдущих. У вас именно такой алгоритм?
3. Параллельное программирование само по себе непростая штука, даже без использования графических ускорителей. Потому очень рекомендуется распараллелить свой алгоритм сначала чем-нибудь попроще, например с помощью OpenMP. Там параллельность включается одной директивой… только не забудьте, что если в цикле используются какие-то буферные переменные, то в параллельном исполнении они должны быть размножены на количество итераций или заводиться внутри цикла!
4. Чтоб не потерять десятки часов, нужно быть 100% уверенным, что хотя бы параллельная часть алгоритма программы полностью свободна от ошибок работы с памятью. Это достигается, например, с помощью valgrind. Также эта чудесная программка умеет ловить ошибки распараллеливания через OpenMP, так что лучше выловить все заранее, пока не попало на ускоритель — там инструментов намного меньше.

Учет особенностей работы ускорителя


1. Нужно понимать, что ускоритель работает с собственной памятью, объем которой ограничен, а трансфер туда-сюда довольно дорог. Конкретные цифры зависят от конкретной системы, но этот вопрос придется «держать в голове» все время. Лучше всего с графическими ускорителями работают алгоритмы, которые принимают не так много (но не меньше количества нитей!) данных, и достаточно долго их математически обрабатывают. Достаточно, но не очень долго, во многих системах установлен лимит на время максимального исполнения нити!
2. Память туда-сюда копируется неразрывными областями. Потому, например, обычные для Си N мерные массивы, организованные как массивы указателей на указатели совершенно не подходят, приходится использовать линейно организованные многомерные массивы данных.
3. Во «внутреннем» коде, исполняемом на ускорителе, нет операций выделения-освобождения памяти, ввода-вывода, невозможна рекурсия. Ввод-вывод, временные буфера обеспечиваются кодом, исполняемым на центральном процессоре.
4.«Идеальный» для ускорителя алгоритм — когда один и тот же код работает для разных данных (SIMD), когда код от них не зависит (пример — сложение векторов). Любое ветвление, любой цикл с переменным, зависящим от данных числом итераций дают значительное замедление.

Некоторые выводы


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

Использованные материалы:
NVIDIA OpenCL
Цикл статей на Хабре
OpenCL for Mac OS X

Похожие публикации

AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама

Комментарии 20

    0
    Очень интересно, спасибо!

    А какие задачи вы решали с помощью этой технологии? Хотя бы в общем.
      +4
      Скрининг по гомологии, алгоритмы группы genbee, www.bri-shur.com
      Сейчас там стоит OpenMP шная версия т.к. два серверных nehalem рвут по производительности достаточно слабую карточку GF120 на текущем (честно говоря — очень тяжелом для массового параллелизма) алгоритме.
      На моем же рабочем компьютере FERMIшная GTS450 ненамного, но обходит i5-650.
      FERMI, по моему опыту, гораздо лучше работает с «плохими» алгоритмами, хотя там еще пахать и пахать.
      Сейчас только что закончилась конференция ПаВТ-2011, выступал представитель NVIDIA представляя CUDA 4. Говорил что одна из основных задач — уменьшить специфичность программирования граф. ускорителей.
      Но до конца все равно не удастся, все равно будет SIMD. Может, хоть с памятью разберутся — сейчас приходится играть с банками данных и распараллеливать данные даже на чтение (именно в этом Fermi лучше предыдущих архитектур).
      В общем, все очень интересно, параллельное программирование — очень отдельная и сложная тема, распараллеливать алгоритм на миллион ядер пока никто не умеет, а уже нужно.
        0
        Все это очень интересно звучит, спасибо. Столько тем для статей! Напишете?
          +7
          Да. Затем сюда и пришёл. На той же ПАВТ всего два доклада с реальным ускорением на параллельных ускорителях для сложных реальных задач (распознаватели речи и пермские двигателисты).
          По OpenCL в рунете — почти исключительно Хабр.
          Это все очень мало, начало. Будем работать!
      +4
      В целях восстановления кислотно-щелочного баланса расскажу немножко про CUDA.

      «Цена вхождения» в эту технологию гораздо ниже, чем многие думают. Видеокарта (GF8600 или любая более новая) и компилятор C — это всё, что требуется для работы (желательно иметь вторую видеокарту или второй комп с GPU для дебаггера GPU-кода). Загрузить CUDA и GPU Computing SDK — и всё, можно работать. Документация очень подробная, примеров в SDK полно, также к вашим услугам весьма компетентный форум на nvidia.com. Причём писать можно сразу на OpenCL — он у NVIDIA вполне нормальный, afaik.

      С недавнего времени для предварительной отладки сложных алгоритмов можно использовать MATLAB — там есть возможность запускать код на GPU. Ну и свои библиотеки у NVIDIA вполне достойные — CUFFT, CUBLAS, NPP.

      В общем, дерзайте. Мне странно, что у такой перспективной технологии у нас в России до сих пор столь небольшое количество пользователей.
        0
        По докладу пермяков (у них индустриальный подход, попробовали под свой алгоритм обе технологии и все доступные ускорители, и Intel и AMD, штук 8) на их задаче не было разницы в скорости CUDA-OpenCL, а AMDшные решения оказались чуть быстрее.
        С подходом (CUDA-заказные, OpenCL-универсальные) соглашусь. Впрочем, внутренняя логика программирования у этих технологий практически одинаковая, они оба достаточно низкоуровневые и «железо» диктует и возможности, и проблемы.
          0
          Я еще не написал про грабли, связанные с банками памяти… Но это уже тонкие оптимизации, доступные в документации. В статье я постарался сконцентрироваться на не вполне очевидных вещах, без которых нельзя программировать даже если знаешь саму технологию. В документации они описаны, по моему мнению, недостаточно.
          0
          Тоже довольно долго бодался с OpenCL.
          Я бы в статье выделил ещё тот факт, что наибольшая производительность технологии достигается при использовании векторов, векторных операций и текстур (изображений). Поэтому лучше сразу проектировать алгоритм с данными, запакованными в int4/float4.
          0
          Если пишите штучное ПО под которое можно подобрать аппаратную часть, то лучшим вариантом будет CUDA у неё кстати есть возможность выделять память динамически, но если массово, OpenCL не оставляет вариантов, потому как например говорить геймерам купите себе карточку NVIDIA для того что бы увидеть супер реалистичную физику в игре — это плохо.
            0
            Да, возможность работы с динамической памятью в коде на ускорителе была анонсирована в CUDA 4.
            CUDA пытаются сделать кроссплатформенным стандартом (проект OCELOT) но я в это не очень верю.
            У OpenCL еще один козырь появился — AMD начинает выпуск своих ускорителей вычислений (типа Tesla)
            0
            а карточки Tesla вообще используются в этих решениях? а то большинство статей, что я читал про работу с CUDA, говорили об использовании обычных видеокарт и слабом приросте в реальных задачах по сравнению с CPU.
              0
              Все зависит от задачи.
              Топовые графические карты быстрее и дешевле Tesla.
              Но
              1) У них меньше объем (видео)памяти. Это критично, например, для нашей молекулярной динамики — большую модель просто не загрузишь.
              2) На них менее надежные вычисления. Если на игровой карте раз в час игры промелькнет артефакт, это допустимо. А вот если неправильно посчитается тот же реактивный двигатель… На теслах есть контроль памяти по четности, для критичных алгоритмов, которые считаются сутками, это критично, иначе придется покупать две карты, запускать одинаковые задачи и сравнивать результат для верификации.
              3) Сам встречался с тем, что на граф. карте есть предел по времени на одну нитку вычислений, если она «думает» больше, считается зависшей и прибивается, для графики это допустимо — для вычислений — нет.

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

              В общем, все зависит от задач. Сейчас нам (программистам) светит смена парадигмы программирования, переход на параллелизацию всего и вся. Постараюсь в ближайшее время по материалам конференции написать на Хабре статью.
              Все это очень интересно, придется много учиться.
                0
                «На них менее надежные вычисления.» — Я не согласен. Вы о каких картах сейчас? Потому, что в спецификации OpenCL есть конкретно то как должно работать с флоат-поинт арифметикой: «Defines consistent numerical requirements based on IEEE 754». У CUDA етого нету. Я сам сравнивал разброс подсчета больших матрих на GPU и CPU, и я практически не видел разницы в том, кто считает лучше, и там и там были очень похожии разбросы.
                  0
                  Я про неустойчивость результата при длительных вычислениях (сутки и более).
                  Даже на конференции один из докладчиков рассказывал, что при подсчете на двух картах получались разные результаты. Проверифицировали третьей, одна оказалась несколько глючной. Это критично на научных задачах.
                  Также опираюсь на статью в журнале «Суперкомпьютеры», её, к сожалению, нет на их сайте. Там сравнивались теслы и топовые игровые карты.
                    0
                    А какие выводы из этих сравнений тесл и игровых карт?
                    Если я не ошибаюсь, так китайцы себе поставили суперкомпютер на АМД картах. А для устойчивости они их подтактировали…
                    Пруф линк искать не буду.
                      0
                      Выводы я уже озвучил — для больших по времени или памяти задач — тесла.
                      О! Нашел-таки на сайте статью!
                      Сейчас на первом месте китайский комп на tesla. Вроде был еще один на amd
                      http://hitech.newsru.com/article/15nov2010/cnno1
                      но в последних рейтингах я его не нашел, видимо произвели апгрейд на тесла.
                      китайцы на www.top500.org
                  0
                  Спасибо

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

              Самое читаемое