- •Нижегородский государственный университет им. Н.И. Лобачевского
- •Содержание
- •Архитектура GPU NVIDIA
- •Архитектура CPU и GPU
- •Архитектура CPU и GPU
- •Архитектура GPU: общие сведения
- •Архитектура Tesla 8/10
- •Мультипроцессор Tesla 8
- •Мультипроцессор Tesla 10
- •Иерархия памяти Tesla 10
- •Мультипроцессор Fermi
- •Архитектура Fermi
- •Вычислительные возможности
- •Вычислительные возможности
- •Исполнение потоков
- •Основные понятия
- •Взаимодействие потоков
- •Выполнение блоков
- •«Автоматическая масштабируемость»
- •SIMT
- •Пример выполнения варпов
- •Выполнение ветвлений
- •Оптимизация загрузки устройства
- •Иерархия памяти CUDA
- •Типы памяти и скорость доступа
- •Использование локальной памяти
- •Использование константной памяти
- •Использование константной памяти
- •Использование текстурной памяти
- •Использование глобальной памяти
- •Использование глобальной памяти
- •Пример: выделение памяти и копирование вектора
- •Эффективная работа с глобальной памятью
- •Эффективная работа с глобальной памятью
- •Эффективная работа с глобальной памятью
- •Пример доступа к глобальной памяти
- •Пример доступа к глобальной памяти
- •Пример доступа к глобальной памяти
- •Рекомендации по эффективной работе с глобальной памятью
- •Пример
- •Работа с разделяемой памятью
- •Работа с разделяемой памятью
- •Пример
- •Динамически выделяемая разделяемая память
- •Пример
- •Эффективная работа с разделяемой памятью
- •Эффективная работа с разделяемой памятью
- •Доступ к разделяемой памяти без конфликтов банков
- •Доступ к разделяемой памяти с конфликтами банков
- •Пример: параллельная редукция
- •Постановка задачи
- •Иерархическое суммирование
- •Вариант 1
- •Вариант 1
- •Вариант 2
- •Вариант 2
- •Вариант 3
- •Вариант 3
- •Вариант 4
- •Вариант 4
- •Вариант 5
- •Результаты
- •Материалы
Использование глобальной памяти
Выделение и освобождение памяти на устройстве:
–cudaError_t cudaMalloc (void** devPtr, size_t count) – выделяет память на устройстве и возвращает указатель на нее;
–cudaError_t cudaFree (void* devPtr) – освобождает память на устройстве.
Копирование данных между хостом и устройством:
–cudaError_t cudaMemcpy (void* dst, const void* src, size_t count, enum cudaMemcpyKind kind),
kind может принимать значения cudaMemcpyHostToDevice и cudaMemcpyDeviceToHost.
– cudaMemcpyAsync – неблокирующий вариант.
Н. Новгород, 2012 г. |
Исполнение потоков. Иерархия памяти |
31 |
Пример: выделение памяти и копирование вектора
Выделение памяти на хосте и устройстве: int n = 1000;
float * a = new float[n], * a_gpu; cudaMalloc((void**)&a_gpu, n *
sizeof(float));
Копирование с хоста на устройтво: cudaMemcpy(a_gpu, a, n * sizeof(float),
cudaMemcpyHostToDevice);
Копирование с устройства на хост: cudaMemcpy(a, a_gpu, n * sizeof(float),
cudaMemcpyDeviceToHost);
Н. Новгород, 2012 г. |
Исполнение потоков. Иерархия памяти |
32 |
Эффективная работа с глобальной памятью
L1/L2 кэш для глобальной памяти появился в архитектуре Fermi.
Латентность 400-600 тактов (без учета кэша или в случае кэш-промаха).
Оптимизация работы с глобальной памятью обычно имеет очень большое значение.
Н. Новгород, 2012 г. |
Исполнение потоков. Иерархия памяти |
33 |
Эффективная работа с глобальной памятью
Доступ в глобальную память осуществляется полуварпами.
Каждый поток обращается к 32-, 64- или 128-битным словам.
При выполнении определенных условий происходит
объединение запросов (коалесцирование, coalescing) к памяти всех потоков полуварпа в одну операцию доступа к непрерывному блоку памяти и выполнение их одной инструкцией.
В противном случае доступ полуварпа к памяти разбивается на несколько последовательных доступов к непрерывным блокам памяти.
Условия для объединения запросов зависят от вычислительных возможностей, постепенно они становятся все более мягкими.
Н. Новгород, 2012 г. |
Исполнение потоков. Иерархия памяти |
34 |
Эффективная работа с глобальной памятью
Условия, необходимые для объединения запросов:
–Доступ в пределах одного последовательного участка памяти определенного размера.
–Выровненность адресов, с которыми работает каждый поток, по размеру типа. Выровненность автоматически обеспечивается для встроенных векторных типов, для обеспечения выровненности структур используется __align__ (newsize) при их объявлении.
Н. Новгород, 2012 г. |
Исполнение потоков. Иерархия памяти |
35 |
Пример доступа к глобальной памяти
[NVIDIA CUDA C Programming Guide v. 4.0]
Н. Новгород, 2012 г. |
Исполнение потоков. Иерархия памяти |
36 |
Пример доступа к глобальной памяти
[NVIDIA CUDA C Programming Guide v. 4.0]
Н. Новгород, 2012 г. |
Исполнение потоков. Иерархия памяти |
37 |
Пример доступа к глобальной памяти
[NVIDIA CUDA C Programming Guide v. 4.0]
Н. Новгород, 2012 г. |
Исполнение потоков. Иерархия памяти |
38 |
Рекомендации по эффективной работе с глобальной памятью
За счет объединения запросов можно добиться значительного уменьшения времени на доступ к глобальной памяти.
Объединение запросов заведомо невозможно, когда адреса, по которым обращаются потоки одного полуварпа, расположены далеко друг от друга.
Для обеспечения объединения запросов обычно стоит предпочитать регулярные структуры данных нерегулярным.
В случае независимой обработки вместо массива структур обычно лучше использовать массивы отдельных компонент.
Н. Новгород, 2012 г. |
Исполнение потоков. Иерархия памяти |
39 |
Пример
/* Одна итерация метода Якоби для системы размера n на n: x0
– текущее приближение, x1 – следующее, матрица a хранится по строкам, f – правая часть. Каждый поток вычисляет свой
элемент вектора x1, общее число потоков равно n. */
__global__ void kernel (float * a, float * f, float * x0, float * x1, int n)
{
int idx = blockIdx.x * blockDim.x + threadIdx.x; int ia = n * idx;
float sum = 0.0f;
for (int i = 0; i < n; i++)
sum += a[ia + i] * x0[i]; /* плохой вариант доступа к a, лучше хранить ее по столбцам */
float alpha = 1.0f / a[ia + idx];
x1[idx] = x0[idx] + alpha * (f[idx] - sum);
} |
Использованы материалы: А.В. Боресков, А.А. Харламов «Архитектура и |
||
|
|||
|
|
программирование массивно-параллельных вычислительных систем» |
|
|
Н. Новгород, 2012 г. |
Исполнение потоков. Иерархия памяти |
40 |
