Пример оптимизации вычислений на CUDA

Введение


Я описываю результаты применения способов оптимизации вычислений на CUDA при моделировании плазмы. Вычисления производятся с использованием Java-привязки к CUDA (JCUDA) [1] на GT630 (Kepler). Моделирование происходит как решение задачи Коши — задание значений параметров в начальный момент времени, затем приращение времени и перерасчет всех уравнений, и т.д. многократно. Вычисления происходят в двойной точности (double). Правильность полученных результатов подтверждена вычислениями на CPU без JCUDA.

Модель параметрической неустойчивости ленгмюровских волн в плазме состоит из уравнений амплитуды, фазы, плотности ионов, напряженности электрического поля (число уравнений каждого типа равно 400), уравнений движения ионов, число которых равно 20000, и двух уравнений накачки. Библиотеки функций (cublas и т.д.) не используются, код уравнений для вычислений на GPU написан руками в .cu файле.

1 Применение основных способов оптимизации вычислений на CUDA


1.1. Важно свести к минимуму передачу данных между памятью GPU и ОЗУ, даже если это означает запуск участков кода на GPU, которые не демонстрируют ускорение по сравнению с CPU [2]. Так, непараллельно происходит вычисление параметров накачки на GPU, т.к. они описываются только двумя уравнениями. Их вычисление на CPU происходило бы быстрее, однако требовало бы затрат времени на обмен данными.

1.2. Исходные данные для расчета загружаются в память GPU единожды перед началом моделирования. Далее обмен между ОЗУ и GPU отсутствует кроме моментов времени, результаты которых нужно сохранить.

1.3. Вычисления всех уравнений, кроме расчета накачки, происходят параллельно (для вычисления одного уравнения создается один поток). Подбираются размерности сетки и блока, при которых скорость расчета максимальна. Размерность блока (число потоков в блоке) не должна быть маленькой и большой, по собственному опыту, должна равняться приблизительно числу ядер в GPU (по крайней мере в GPU до 500 ядер).

1.4. Все загружаемые в память GPU данные хранятся в глобальной памяти, но GPU обладает быстрыми типами памяти — разделяемой (shared) и константной (constant). Однако попытки их использовать дали эффект всего 1%.

1.5. В некоторых местах кода много раз выполняются одинаковые вычисления. Например, если присутствует повторяющееся a*b, создается переменная c=a*b, которая затем используется. Подобным образом были сделаны несколько оптимизаций, однако их эффект 1%.

2 Оптимизация использования тригонометрических функций


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

2.1. Существуют функции sinpi, cospi, однако в модели только 4 функции имеет подходящий вид, а эффект от их использования составляет 2%.

2.2. Также существует функция sincos, одновременно рассчитывающая синус и косинус. Эффект от ее использования составляет 50%. Однако существенным недостатком является необходимость для каждого вычисления выделять память под хранение значений синуса и косинуса, что усложняет ее использование.

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

2.4. В CUDA каждая мат. функция имеет несколько реализаций, отличающихся по точности – double-функции (sin, cos), float-функции (sinf, cosf), функции пониженной точности (__sinf, __cosf). Так, применение float-функций синуса и косинуса позволяет ускорить вычисление уравнений на 60%, а применение функций синуса и косинуса пониженной точности — на 70%. При этом другие расчеты продолжают выполняться в двойной точности, а точность результатов сохраняется.

Выводы


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

Время моделирования после оптимизации составляет 7 минут, из них 90% — вычисления на GPU (CUDA), 10% — дополнительные вычисления на CPU, связанные с сохранением результатов (Java), обмен данными между памятью GPU и ОЗУ — 0.01%.

Успешные способы — 1.1, 1.2, 1.3, 2.4 — минимизирован обмен данными между памятью GPU и оперативной памятью, произведен перенос основных вычислений на GPU и их распараллеливание, выбраны оптимальные параметры распараллеливания – размер сетки и блоков, использованы тригонометрические функции пониженной точности.

Способы, от которых пришлось отказаться из-за низкой эффективности или усложнения кода — 1.4, 1.5, 2.1, 2.2, 2.3 — предварительный расчет значений с целью уменьшения числа вычислений, попытки использования быстрых видов памяти GPU.

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

В исследовании проведено моделирование несколько сотен раз, в т.ч. иногда с большим числом частиц (увеличение числа частиц в 2 раза увеличивает время моделирования в 4 раза). Поэтому небольшая экономия времени за одно моделирование дает большую экономию в итоге. Возможности провести моделирование на более мощной видеокарте нет. Не слишком корректное сравнение, но ускорение на JCUDA по сравнению с вычислениями на Java на одном ядре процессора 2,2 ГГц составляет от 35 до сотни раз в зависимости от выбранных параметров счета. Также наработки используются в других задачах.

Литература


1. Marco Hutter. JCUDA. jcuda.org.
2. CUDA C Best Practices Guide. NVIDIA Corporation. docs.nvidia.com/cuda/cuda-c-best-practices-guide.

Работы, входящие в одно исследование с данной статьей (добавлено 05.02.2014)


1. Детальнее об оптимизации написано в статье it-visnyk.kpi.ua/wp-content/uploads/2014/01/Issue-58.pdf (страницы 125-130).
Цифры немного отличаются, но суть та же.
Приймак А.В. Оптимизация вычислений на CUDA при моделировании неустойчивости ленгмюровских волн в плазме. // Вісник НТУУ «КПІ». Інформатика, управління та обчислювальна техніка: Зб. наук. пр. – К.: Век+, – 2013. – № 58. – C. 125-131.
2. Описание моделируемой задачи vant.kipt.kharkov.ua/TABFRAME.html (выбрать 2013 №4(86))
Belkin E.V., Kirichok A.V., Kuklin V.M., Pryjmak A.V., Zagorodny A.G. Dynamics of ions during development of parametric instability of Langmuir waves // Вопросы атомной науки и техники. Серия «Плазменная электроника и новые методы ускорения». 2013, №8, с.260-266.
3. Об использовании JCUDA csconf.donntu.edu.ua/arxiv (материалы еще не размещены)
Приймак А.В. Использование технологии JCUDA для моделирования динамики ионов при развитии параметрической неустойчивости ленгмюровских волн. – Информатика и компьютерные технологии / Сборник трудов IX международной научно-технической конференции студентов, аспирантов и молодых ученых. – 5-6 ноября 2013, Донецк, ДонНТУ. – 2013. – С. 200-204.
4. О программном обеспечении для моделирования conferences.neasmo.org.ua/node/2924
Приймак А.В. Разработка программного обеспечения для гибридных моделей модуляционной неустойчивости ленгмюровских волн в плазме. Материалы ХVІІ Международной научно-практической интернет-конференции «Проблемы и перспективы развития науки в начале третьего тысячелетия в странах СНГ» // Сборник научных трудов. — 29-30 ноября 2013, Переяслав-Хмельницкий, Переяслав-Хмельницький ДПУ ім.Г.Сковороди. – С.155-159.
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

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

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

    +16
    Хорошо, но мало. Где примеры? Где графики? Тема-то очень интересная.
    Курсовая (или дипломная?) неплоха, но вот в качестве статьи не очень пока, увы.
      +1
      Добавил связанные материалы внизу статьи «Работы, входящие в одно исследование с данной статьей (добавлено 05.02.2014)».
      Детали там, по правилам я не могу их разместить здесь. Однако про проведение оптимизации все равно подробностей недостаточно, но это повод для новой статьи.
      –6
      Двойная точность на GT630?
      По-моему, любой современный 4х ядерный процессор порвет в двойной точности эту карту в разы:-)
        0
        Возмущение, конечно, понятно, GT630 для двойной точности не лучший выбор, но думаю не, не порвет, будет просто незначительно лучше, чем CPU. К автору: было бы интересно посмотреть сравнительные графики CPU/GPU или хотя бы комментарий по поводу был ли вообще профит и если да, то какой? или
        Время моделирования до оптимизации использования тригонометрических функций составляло 20 минут.
        относится к коду на CPU?
          0
          20 минут относится к коду на GPU.

          На CPU считалось на 1 ядре на Java. Т.к. Java медленный, то ускорение на CUDA по сравнению с Java я получал не менее 35 раз.
            0
            Тогда все ясно. Вопрос снимается. 1 поток на яве против CUDA :-)
            А можете протестировать на мощной карте? gtx titan например? :-)
              0
              возможности нет, к сожалению
                0
                Задача из консоли пускается? под linux работает?
                  0
                  только win7, описание ПО вкратце здесь можно скачать статью conferences.neasmo.org.ua/node/2924
                    0
                    Печально, что на win7. Не запустить на нормальных суперкомпьютерах :-)
                    Останусь при своем мнении, что не так быстра gt630, как медленно работал ява код на CPU.
                      0
                      не спорю)
                        0
                        Эта задача для обычного домашнего пк. Если взять намного больше частиц, то GT 630 не справится, но этого и не требуется.
            +1
            По-моему, любой современный 4х ядерный процессор порвет в двойной точности эту карту в разы:-)

            Это у вас, наверное, впечатления от 4хх (и более ранних) остались. В 6хх работу с double здорово ускорили. А сравнивать 4(8) параллельных потоков с несколькими тысячами немного смешно.
              +1
              Вы ошибаетесь, как раз наоборот, в 6хх работу с двойной точностью сильно урезали. Только в титанах (ну и теслах конечно) оставили 1\3 от одинарной, в остальных картах двойных блоков 1\24 от кол-ва одинарный блоков. В 5хх и 4хх сериях коэф. был по-моему 1\8.
              Поэтому, например, в двойной точности gtx 570 будет гораздо быстрее gtx670.

              Даже последняя GT 630 имеет всего 1-2 SMX, или 192-384 cuda ядер, т.е. всего 8-16 блоков двойной точности на 0.9ГГц.
              И таки да, их смешно сравнивать с 4 ядрами на 3 ГГц, умеющих обрабатывать 4-8 double за такт (AVX-AVX2) :-)
            0
            А у CUDA есть какие-то преимущества (кроме C ) перед OpenCL?
              0
              Более популярный пока, лучше оптимизирован под возможности родных карт nvidia ( и то благодаря почти полному забиванию на OpenCL), больше наработок, средств для программеров и т.п.
              В остальном минусы.
              Всё IMHO.
              +1
              А можно код? И скриншоты с nvidia cuda profiler.
                0
                nvidia cuda profiler не использую. Считаю через JCUDA, и похоже, nvidia cuda profiler не получиться использовать.

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

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