- •Аннотация
- •Оглавление
- •Введение
- •1. Графические ускорители – как эффективный путь повышения производительности вычислительных архитектур
- •1.1. Этапы развития графических ускорителей и их устройство
- •1.1.1. Основная терминология и устройство графического адаптера
- •1.1.2. Архитектура современныхGpu
- •1.2. Подход к использованию графических ускорителей для вычислений общего назначения
- •1.2.1.GpgpUподход
- •1.2.2. Гибридные вычислительные системы
- •1.2.3. Программная модельCuda
- •1.3.OpenAcc. Новейший стандарт разработкиGpgpu-приложений
- •1.3.1. Возможности стандарта
- •1.3.2. Модель выполнения
- •1.3.3. Модель памяти
- •1.4. Выводы по разделу 1
- •2. Постановка задачи магистерской диссертации
- •2.1. Цели и задачи исследования
- •2.2. Математическая постановка задачи решения трехдиагональной системы линейных уравнений методом блочной прогонки
- •2.3. Разработка параллельного алгоритма для решения трехдиагональной системы линейных уравнений
- •2.4. Выводы по разделу 2
- •3. Реализация и исследование разработанного алгоритма
- •3.1. Структура параллельной программы и особенности реализации
- •3.2. Результаты тестирования
- •3.3. Анализ результатов
- •3.4. Выводы по разделу 3
- •Заключение
- •Список использованных источников
- •Приложение 1. История развития графических ускорителей и их устройство
- •1.1. Устройство графического адаптера
- •1.2. Рынок графических адаптеров
- •1.3. АрхитектураGpugt200
- •1.4. Современное положение дел
- •Приложение 2. Основная часть программного кода разработанного приложения
1.3.3. Модель памяти
Самое существенное отличие программы, выполняющейся только на хосте, от GPGPU-программы в том, что память ускорителя физически отделена от памяти ускорителя. Если мы, к примеру, рассматриваем современные графические адаптеры, память ускорителя располагается непосредственное на печатной плате ускорителя. В этом случае нить хоста не может осуществлять операции чтения или записи в память ускорителя напрямую, потому что она не отображается в виртуальной памяти нити хоста. Все перемещения данных между памятью хоста и памятью ускорителя должны выполняться нитью хоста через системные вызовы, которые явно перемещают данные между раздельными типами памятями, обычно, с использованием метода прямого доступа к памяти (directmemoryaccess,DMA). Кроме того, является недопустимым предположение о том, что ускоритель может читать или писать в память хоста, хотя это поддерживается некоторыми ускорителями, часто со значительным снижения производительности.
Концепция раздельной памяти хоста и ускорителя совершенно очевидна в низкоуровневых языках программирования ускорителей, таких, как CUDAилиOpenCL, в которых перемещение данных между памятями может преобладать в коде программы. В моделиOpenACCперемещение данных между памятями может быть неявным и управляться компилятором, основываясь на директивах, которые указал программист. Однако, при написании программ наOpenACCнужно быть в курсе о раздельной памяти хоста и ускорителя по многим причинам, в том числе, но не ограничиваясь, следующими:
Пропускная способность памяти между хостом и ускорителем определяет уровень вычислительной интенсивности, необходимый для эффективного ускорения данного участка программы,
Ограниченный размер памяти ускорителя может препятствовать выгрузке участков программы, которые оперируют очень большими объемами данных,
Адреса, хранящиеся в указателях на хосте, могут быть действительны только на хосте; адреса, хранящиеся в указателях на ускорителе, могут быть действительны только на ускорителе. Разыменование указателей хоста на ускорителе или разыменование указателей ускорителя на хосте будет некорректным.
OpenACCпредоставляет доступ к раздельной памяти с помощью среды данных устройства. Данные на ускорителе имеют явный срок службы, с того момента, как память выделяется или создаётся, и до того момента, как данные уничтожаются. Если устройство разделяет физическую и виртуальную память с локальной нитью, среда данных ускорителя будет использоваться совместно с локальной нитью. В этом случае нет необходимости реализовывать создание новых копий данных на ускорителе и никаких перемещений данных делать не нужно. Если ускоритель использует физически или виртуально разделённую память локальной нити, будет выделена новая память на ускорителе и данные будут скопированы из локальной памяти в среду ускорителя.
В современных графических ускорителях реализована слабая модель памяти (weakmemorymodel) [8]. В частности, они не поддерживают когерентность памяти между операциями, выполняемыми различными нитями; даже в одном и том же вычислительном блоке, когерентность памяти гарантируется только, когда операции с памятью явно разделены. В противном случае, если одна нить пытается обновить значение в ячейке памяти и другая нить читает значение из той же ячейки, или две нити пытаются записать значение в одну и ту же ячейку памяти, на аппаратном уровне может не гарантироваться одинаковый результат при разных запусках программы. В то время, как компилятор может выявить некоторые потенциальные ошибки такого рода, это тем не менее возможно написать параллельный код, который к противоречивым численным результатам.
Некоторые современные ускорители имеют программно-управляемый кэш, некоторые имеют аппаратно-управляемый кэш, и большинство имеют аппаратный кэш, который может быть использован только для определённых целей и имеет ограничение “read-only”. В низкоуровневых программных моделях, таких, как в языкахCUDAилиOpenCL, управление кэшами зависит от программиста. В моделиOpenACC, эти кэши управляются компилятором с подсказками от программиста в виде директив.