Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Лекции / Лекция 12

.doc
Скачиваний:
31
Добавлен:
06.07.2016
Размер:
20.99 Кб
Скачать

Технологии и методы программирования. Лекция 12.

Программирование для графических процессоров.

Технология CUDA (NVIDIO).

CUDADriver – блок, обеспечивающий выполнение программ.

CUDATovloit – инструкции разработки.

NTII – компилятор.

CPU Computering SDK – набор шаблонов, примеров.

Модель исполнения.

Графический процессор — набор мультипроцессоров, состоящих из CUDA-ядер и модулей для реализаций вычислительных функций. Каждый модуль имеет конвейер, разделяемую и кэш-память. CUDA технология предполагает определение спецфункций (тоже ядер), исполняемых параллельно на графическом процессоре в множестве потоков. Потоки объединяются в блок, где они могут взаимодействовать с использованием общих данных из разделяемой памяти (быстро). Взаимодействие процессов из разных блоков происходит медленнее. Блоки, в свою очередь, объединяются в решётку. В решетке к блокам идёт обращение через координаты (возможны одно-, двух- и трёхмерные). При этом используется встроенная переменная blockIdx. Потоки в блоках тоже определяются координатами, но из переменной threadIdx.

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

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

Global void matAdd(float *A, float b, float C, int N){

int i=blockIdx.x*BlockDim.x+threadIdx.x;

int j=blockIdx.y*BlockDim.y+threadIdx.y;

if (i<N && j<N){

c[i*N+j]=A[i*N+j]+B[i*N+j];

}

}

Структура памяти.

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

Спецификаторы типов функций:

Device – определяет функцию, выполняющуюся на графическом процессоре и вызываемую только на нём.

Global – выполняющуюся на графическом процессоре и вызывающуюся с обычного.

Host – выполняющуюся на обычном процессоре и вызывающуюся только там.

Device и global не имеют объявления статических переменных, не поддерживают переменное число аргументов. Global и host вместе не употребляются. Global долен возвращать void. Вызов global асинхронен - после запуска функции управление возвращается сразу же.

Спецификаторы переменных:

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

Constant – размещается в константной памяти, доступна всем потокам графического процессора.

Chared – размещается в разделяемой памяти, для каждого блока — свой экземпляр. Существует, пока существует блок, доступна всем его потокам.

Правила и ограничения:

(не применимы к параметрам и к локальным переменным функций графического процессора)

- Chared и Constant определяют переменные статического хранения, не могут определять внешние переменные. Должны быть объявлены в глобальном пространстве имён.

- Constant определяет переменную, инициализируемую только из ЦПУ функциями времени выполнения.

- Chared нельзя инициализировать при объявлении.

- Переменная, объявленная в функции графического процессора без спецификаторов, размещается в регистрах, большие структуры/массивы — в локальной памяти.

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

В CUDA-приложениях доступны следующие переменные:

gridDim типа dim3 – размерность решетки

blockIdx типа vint3 – индекс блока в решетке

blockPim типа dim3 – размер блока потоков

threadIdx типа uint3 – индекс потока в блоке

warpsize типа int – размер варпа.

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

Конфигурирование исполнения ядер.

Каждому вызову функции со спецификатором Global должна предшествовать конфигурация ядра. При этом задаётся размерность решётки и блоков. <<grid, block, stream>> - помещается между именем функции и аргументами.

Соседние файлы в папке Лекции