Upload
cs-center
View
278
Download
1
Embed Size (px)
Citation preview
Иерархия памяти
Храмченков Э.М.1,2
1. Казанский федеральный университет
2. НИИСИ РАН
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Организация памяти и работы с ней на CPU и GPU существенно отличаются
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Память GPU
Организация памяти и работы с ней на CPU и GPU существенно отличаются
CPU – основная площадь схемы занята кешами
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Память GPU
Организация памяти и работы с ней на CPU и GPU существенно отличаются
CPU – основная площадь схемы занята кешами
GPU – основная часть отведена под вычислительные блоки
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Память GPU
Организация памяти и работы с ней на CPU и GPU существенно отличаются
CPU – основная площадь схемы занята кешами
GPU – основная часть отведена под вычислительные блоки
В GPU существует несколько видов памяти - некоторые в мультипроцессорах, другие в DRAM
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Память GPU
Организация памяти и работы с ней на CPU и GPU существенно отличаются
CPU – основная площадь схемы занята кешами
GPU – основная часть отведена под вычислительные блоки
В GPU существует несколько видов памяти - некоторые в мультипроцессорах, другие в DRAM
Эффективное использование памяти – один из важнейших элементов написания быстрого кода
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Память GPU
Тип памяти Доступ Видимость Скорость Расположение
Регистры R/W Per-thread Высокая SM
Локальная R/W Per-thread Низкая DRAM(device)
Разделяемая R/W Per-block Высокая SM
Глобальная R/W Per-grid Низкая DRAM(device)
Константная R/O Per-grid Высокая DRAM(device)
Текстурная R/O Per-grid Высокая DRAM(device)
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Память GPU
Регистры – наиболее простой вид памяти:
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Регистры
Регистры – наиболее простой вид памяти:
Распределяются между потоками блока на этапе компиляции
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Регистры
Регистры – наиболее простой вид памяти:
Распределяются между потоками блока на этапе компиляции
Каждый поток получает в монопольное пользование некоторое количество регистров на все время исполнения ядра
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Регистры
Регистры – наиболее простой вид памяти:
Распределяются между потоками блока на этапе компиляции
Каждый поток получает в монопольное пользование некоторое количество регистров на все время исполнения ядра
Доступ к регистрам других потоков запрещен
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Регистры
Регистры – наиболее простой вид памяти:
Распределяются между потоками блока на этапе компиляции
Каждый поток получает в монопольное пользование некоторое количество регистров на все время исполнения ядра
Доступ к регистрам других потоков запрещен
Расположен в мультипроцессоре – минимальная латентность
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Регистры
Локальная память – используется если регистров не хватает:
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Локальная память
Локальная память – используется если регистров не хватает:
Размещена в DRAM GPU – высокая латентность порядка 400-800 тактов
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Локальная память
Локальная память – используется если регистров не хватает:
Размещена в DRAM GPU – высокая латентность порядка 400-800 тактов
В локальную память всегда попадают union’ы и массивы, размерность которых неизвестна во время компиляции
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Локальная память
Локальная память – используется если регистров не хватает:
Размещена в DRAM GPU – высокая латентность порядка 400-800 тактов
В локальную память всегда попадают union’ы и массивы, размерность которых неизвестна во время компиляции
В локальную память попадают большие структуры и массивы
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Локальная память
Локальная память – используется если регистров не хватает: Размещена в DRAM GPU – высокая латентность
порядка 400-800 тактов
В локальную память всегда попадают union’ы и массивы, размерность которых неизвестна во время компиляции
В локальную память попадают большие структуры и массивы
Все переменные, если ядро использовало все регистры
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Локальная память
Константная (constant) и текстурная (texture) память – расположены в DRAM GPU:
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Constant & texture
Константная (constant) и текстурная (texture) память – расположены в DRAM GPU:
Обладают независимым кешем – высокая скорость доступа
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Constant & texture
Константная (constant) и текстурная (texture) память – расположены в DRAM GPU:
Обладают независимым кешем – высокая скорость доступа
Доступны всем потокам сетки, но только на чтение
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Constant & texture
Константная (constant) и текстурная (texture) память – расположены в DRAM GPU:
Обладают независимым кешем – высокая скорость доступа
Доступны всем потокам сетки, но только на чтение
Запись с CPU с помощью CUDA API
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Constant & texture
Константная (constant) и текстурная (texture) память – расположены в DRAM GPU:
Обладают независимым кешем – высокая скорость доступа
Доступны всем потокам сетки, но только на чтение
Запись с CPU с помощью CUDA API
Общий объем константной памяти – 64КБайт
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Constant & texture
Константная (constant) и текстурная (texture) память – расположены в DRAM GPU:
Обладают независимым кешем – высокая скорость доступа
Доступны всем потокам сетки, но только на чтение
Запись с CPU с помощью CUDA API
Общий объем константной памяти – 64КБайт
Текстурная память – объем равен свободному объему DRAM, но доступ ведется через специальный кеш, работа с данными как с текстурами
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Constant & texture
Глобальная память – память DRAM GPU:
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Глобальная память
Глобальная память – память DRAM GPU:
Высокая латентность – около 800 тактов
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Глобальная память
Глобальная память – память DRAM GPU:
Высокая латентность – около 800 тактов
Может выделяться как с CPU при помощи CUDA API, так и потоками на GPU, с помощью malloc
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Глобальная память
Глобальная память – память DRAM GPU:
Высокая латентность – около 800 тактов
Может выделяться как с CPU при помощи CUDA API, так и потоками на GPU, с помощью malloc
Начиная с архитектуры Fermi кешируется, но эффективность в пересчете на поток незначительна
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Глобальная память
Глобальная память – память DRAM GPU:
Высокая латентность – около 800 тактов
Может выделяться как с CPU при помощи CUDA API, так и потоками на GPU, с помощью malloc
Начиная с архитектуры Fermi кешируется, но эффективность в пересчете на поток незначительна
Может использоваться всеми потоками сетки
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Глобальная память
Глобальная память – память DRAM GPU:
Высокая латентность – около 800 тактов
Может выделяться как с CPU при помощи CUDA API, так и потоками на GPU, с помощью malloc
Начиная с архитектуры Fermi кешируется, но эффективность в пересчете на поток незначительна
Может использоваться всеми потоками сетки
Минимизация доступа к глобальной памяти – основной метод создания эффективного кода
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Глобальная память
Выделяется и освобождается на CPU командами:
cudaError_t cudaMalloc(void ** devPtr, size_t size);
cudaError_t cudaFree(void * devPtr);
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Глобальная память
Выделяется и освобождается на CPU командами:
cudaError_t cudaMalloc(void ** devPtr, size_t size);
cudaError_t cudaFree(void * devPtr);
Доступ к массивам может быть ускорен при наличии выравнивания
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Глобальная память
Выделяется и освобождается на CPU командами:
cudaError_t cudaMalloc(void ** devPtr, size_t size);
cudaError_t cudaFree(void * devPtr);
Доступ к массивам может быть ускорен при наличии выравнивания
Функция для выделения памяти с выравниванием, сдвиг возвращается через параметр pitch:
cudaError_t cudaMallocPitch(void ** devPtr, size_t * pitch, size_t width, size_t height);
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Глобальная память
Указатель от cudaMalloc имеет смысл только для адресного пространства GPU. Для заполнения памяти GPU данными с хоста необходимо использовать команду:
cudaError_t cudaMemcpy ( void * dst, const void * src, size_t size, enum cudaMemcpyKind kind );
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Глобальная память
Указатель от cudaMalloc имеет смысл только для адресного пространства GPU. Для заполнения памяти GPU данными с хоста необходимо использовать команду: cudaError_t cudaMemcpy ( void * dst, const void * src,
size_t size, enum cudaMemcpyKind kind );
Направление копирования определяются параметром kind: host -> device – cudaMemcpyHostToDevice
device -> host – cudaMemcpyDeviceToHost
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Глобальная память
Shared (разделяемая память) – один из важнейших типов памяти:
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Разделяемая память
Shared (разделяемая память) – один из важнейших типов памяти:
Расположена в мультипроцессоре, но выделяется на уровне блоков
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Разделяемая память
Shared (разделяемая память) – один из важнейших типов памяти:
Расположена в мультипроцессоре, но выделяется на уровне блоков
Каждый блок получает в распоряжение одно и то же количество разделяемой памяти
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Разделяемая память
Shared (разделяемая память) – один из важнейших типов памяти:
Расположена в мультипроцессоре, но выделяется на уровне блоков
Каждый блок получает в распоряжение одно и то же количество разделяемой памяти
Размер 48КБайт (+16Кбайт кеша на Fermi)
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Разделяемая память
Shared (разделяемая память) – один из важнейших типов памяти:
Расположена в мультипроцессоре, но выделяется на уровне блоков
Каждый блок получает в распоряжение одно и то же количество разделяемой памяти
Размер 48КБайт (+16Кбайт кеша на Fermi)
Низкая латентность – такая же как у регистров
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Разделяемая память
Shared (разделяемая память) – один из важнейших типов памяти:
Расположена в мультипроцессоре, но выделяется на уровне блоков
Каждый блок получает в распоряжение одно и то же количество разделяемой памяти
Размер 48КБайт (+16Кбайт кеша на Fermi)
Низкая латентность – такая же как у регистров
Может использоваться всеми потоками блока
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Разделяемая память
Эффективно использовать разделяемую память как буфер, вместо обращения к глобальной памяти
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Разделяемая память
Эффективно использовать разделяемую память как буфер, вместо обращения к глобальной памяти
Объем разделяемой памяти делится поровну между всеми блоками потоков, запущенными на мультипроцессоре
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Разделяемая память
Эффективно использовать разделяемую память как буфер, вместо обращения к глобальной памяти
Объем разделяемой памяти делится поровну между всеми блоками потоков, запущенными на мультипроцессоре
Размер разделяемой памяти может быть задан в CUDA-ядре при определении массивов с атрибутом __shared__ или в параметрах запуска ядра
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Разделяемая память
Ситуация – поток А изменяет значение переменной X в разделяемой памяти, поток В должен читать измененное значение
Какое значение в реальности считает поток В
Порядок выполнения потоков не определен – результат операции будет undefined
Чтобы избежать race condition необходима барьерная синхронизация потоков __syncthreads()
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Разделяемая память
Типичный алгоритм:
Загрузка данных из global в shared
__syncthreads ()
Вычисления над этими данными
__syncthreads ()
Запись данных из shared в global
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Синхронизация
Начиная с CUDA 4.0 существует Unified Virtual Addressing (UVA) – общее адресное пространство всех GPU и хоста
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Unified Virtual Addressing
Начиная с CUDA 4.0 существует Unified Virtual Addressing (UVA) – общее адресное пространство всех GPU и хоста
Адреса больше не пересекаются между собой
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Unified Virtual Addressing
Начиная с CUDA 4.0 существует Unified Virtual Addressing (UVA) – общее адресное пространство всех GPU и хоста
Адреса больше не пересекаются между собой
Доступ по указателям из GPU кода, вне зависимости от их фактического размещения
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Unified Virtual Addressing
Начиная с CUDA 4.0 существует Unified Virtual Addressing (UVA) – общее адресное пространство всех GPU и хоста
Адреса больше не пересекаются между собой
Доступ по указателям из GPU кода, вне зависимости от их фактического размещения
Копирование данных между двумя GPU без хост-буфера
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Unified Virtual Addressing
Начиная с CUDA 6.0 и архитектуры GPU Kepler появилась Unified Memory – развитие UVA
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Unified Memory
Начиная с CUDA 6.0 и архитектуры GPU Kepler появилась Unified Memory – развитие UVA
Одинаковый указатель для CPU и GPU памяти
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Unified Memory
Начиная с CUDA 6.0 и архитектуры GPU Kepler появилась Unified Memory – развитие UVA
Одинаковый указатель для CPU и GPU памяти
CUDA автоматически перемещает данные между хостом и GPU
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Unified Memory
Начиная с CUDA 6.0 и архитектуры GPU Kepler появилась Unified Memory – развитие UVA
Одинаковый указатель для CPU и GPU памяти
CUDA автоматически перемещает данные между хостом и GPU
Создание кода значительно упрощается – нет нужды в ручном копировании
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Unified Memory
Начиная с CUDA 6.0 и архитектуры GPU Kepler появилась Unified Memory – развитие UVA
Одинаковый указатель для CPU и GPU памяти
CUDA автоматически перемещает данные между хостом и GPU
Создание кода значительно упрощается – нет нужды в ручном копировании
Это не единая физическая память
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Unified Memory
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Unified Memory
Old Memory Perception New Perception with Unified Memory
Начиная с архитектуры Fermi используются L1 и L2 кеши
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Кеширование
Начиная с архитектуры Fermi используются L1 и L2 кеши
Кеш L1 находится на каждом мультипроцессоре
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Кеширование
Начиная с архитектуры Fermi используются L1 и L2 кеши
Кеш L1 находится на каждом мультипроцессоре
Кеш L2 общий и имеет размер 768 Кбайт
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Кеширование
Начиная с архитектуры Fermi используются L1 и L2 кеши
Кеш L1 находится на каждом мультипроцессоре
Кеш L2 общий и имеет размер 768 Кбайт
Кеш L1 и разделяемая память расположены на одном физическом носителе – 64Кбайт
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Кеширование
Начиная с архитектуры Fermi используются L1 и L2 кеши
Кеш L1 находится на каждом мультипроцессоре
Кеш L2 общий и имеет размер 768 Кбайт
Кеш L1 и разделяемая память расположены на одном физическом носителе – 64Кбайт
Длина кэш-линии составляет 128 байт
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Кеширование
Начиная с архитектуры Fermi используются L1 и L2 кеши
Кеш L1 находится на каждом мультипроцессоре
Кеш L2 общий и имеет размер 768 Кбайт
Кеш L1 и разделяемая память расположены на одном физическом носителе – 64Кбайт
Длина кэш-линии составляет 128 байт
Если размер слова для каждой потока равен 4 байтам, то запросы в память всех 32 потоков варпа объединяются в один
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Кеширование
Выравнивание - при чтении и записи значений глобальной памяти на низком уровне используются выровненные 32-, 64- и 128-битные слова
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Оптимизация доступа в память
Выравнивание - при чтении и записи значений глобальной памяти на низком уровне используются выровненные 32-, 64- и 128-битные слова
Вся выделяемая память CUDA всегда выровнена по 256 байт
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Оптимизация доступа в память
Выравнивание - при чтении и записи значений глобальной памяти на низком уровне используются выровненные 32-, 64- и 128-битные слова
Вся выделяемая память CUDA всегда выровнена по 256 байт
Если адрес объекта невыровнен – требуется больше обращений к памяти
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Оптимизация доступа в память
Выравнивание - при чтении и записи значений глобальной памяти на низком уровне используются выровненные 32-, 64- и 128-битные слова
Вся выделяемая память CUDA всегда выровнена по 256 байт
Если адрес объекта невыровнен – требуется больше обращений к памяти
Чем выше латентность типа памяти, тем важнее выравнивание
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Оптимизация доступа в память
Пример:
struct vec3{
float x, y, z;
};
Размер = 12 байт
Не выровнен в памяти
В случае создания массива – выровненным будет только каждый 4й элемент
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Оптимизация доступа в память
Решение 1 – добавить фиктивный элемент
struct vec3{
float x, y, z, w;
};
Решение 2 – директива выравнивания по 16 байтам
struct __attribute__((aligned(16))) vec3{
float x, y, z;
};
Все элементы расположены по адресам кратным 16
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Оптимизация доступа в память
Coalescing – объединение запросов потоков полуварпа или всего варпа в одно обращение к непрерывному блоку глобальной памяти
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Объединение запросов
Coalescing – объединение запросов потоков полуварпа или всего варпа в одно обращение к непрерывному блоку глобальной памяти
Условия объединения запросов полуварпа:
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Объединение запросов
Coalescing – объединение запросов потоков полуварпа или всего варпа в одно обращение к непрерывному блоку глобальной памяти
Условия объединения запросов полуварпа:
Все нити должны обращаться к 32/64-битным словам, давая в результате 64/128-байтовый блок
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Объединение запросов
Coalescing – объединение запросов потоков полуварпа или всего варпа в одно обращение к непрерывному блоку глобальной памяти
Условия объединения запросов полуварпа:
Все нити должны обращаться к 32/64-битным словам, давая в результате 64/128-байтовый блок
Блок должен быть выровнен по размеру
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Объединение запросов
Coalescing – объединение запросов потоков полуварпа или всего варпа в одно обращение к непрерывному блоку глобальной памяти
Условия объединения запросов полуварпа:
Все нити должны обращаться к 32/64-битным словам, давая в результате 64/128-байтовый блок
Блок должен быть выровнен по размеру
Все 16 слов должны находиться в блоке
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Объединение запросов
Coalescing – объединение запросов потоков полуварпа или всего варпа в одно обращение к непрерывному блоку глобальной памяти
Условия объединения запросов полуварпа: Все нити должны обращаться к 32/64-битным словам,
давая в результате 64/128-байтовый блок
Блок должен быть выровнен по размеру
Все 16 слов должны находиться в блоке
Последовательное обращение – k-ая нить к k-ому слову
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Объединение запросов
На архитектуре Fermi появилось объединение для всего варпа
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Объединение запросов
На архитектуре Fermi появилось объединение для всего варпа
Объединение запросов эффективнее работает со структурами или наборами массивов, чем с массивами структур
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Объединение запросов
На архитектуре Fermi появилось объединение для всего варпа
Объединение запросов эффективнее работает со структурами или наборами массивов, чем с массивами структур
Объединение запросов – потенциальное ускорение CUDA-приложения
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Объединение запросов
Квадратная матрица n×n
n – степень двойки
Два варианта – самый простой, без использования разделяемой памяти и с использованием разделяемой памяти
Примерно 2.7-кратное ускорение
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Транспонирование матрицы
Квадратные матрицы n×n
n – степень двойки
Двумерная сетка блоков, двумерные блоки 16×16
«Наивная» реализация
На каждый элемент:
2N арифметических операций
2N обращений к глобальной памяти
Производительность ограничена пропускной способностью памяти
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Перемножение матриц
Оптимизация «наивного» алгоритма:
Считаем n кратным 16
Для вычисления подматрицы C΄ необходимы лишь полосы A΄ и B΄ размером n×16 исходных матриц А и В
При N=1024 полосы не лезут в shared
Выход – разбиение полос на подматрицы 16×16
C΄ – сумма попарных произведений подматриц из этих полос
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Блочное перемножение матриц
В этом случае C΄ вычисляется за n/16 шагов
На каждом шаге в разделяемую память загружаются 2 подматрицы 16×16
Обращения в глобальную память будут объединены
Требуется 2n/16 обращений в глобальную память
Число арифметических операций осталось 2n
Данные тестов приведены для n=2048
В CUBLAS алгоритм оптимизирован на регистрах
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Блочное перемножение матриц
Алгоритм перемножения Скорость, мс
Без разделяемой памяти 324,63
С разделяемой памятью 93,26
Библиотека CUBLAS 30,84
Computer Science клуб, Казань, 21.10-23.10, 2015 г.
Блочное перемножение матриц