Всем привет!
В начале апреля я увидел анонс новой видеокарты от nVidia, с новым мажорным индексом compute capability – 3.0. Внимательно изучив спеки был удивлён – по всему выходило, что теперь ветвления будут приводить к самым худшим последствиям: большим потерям производительности. Мне нравилось, что от версии к версии ветвления играют всё меньшую роль, а Kepler показался в этом плане шагом назад.
И вот на этой неделе мне пришёл whitepaper по новой числодробилке на архитектуре Kepler и многое прояснил.
Начала
Изначально эта заметка задумывалась только для тех, кто в теме, но на всякий случай поясню что такое compute capability в CUDA.
Итак, компания nVidia разрабатывает видеокарты для общих вычислений вот уже 5 лет. Не сказать, что до этого нельзя было считать на GPU, но делать это было весьма некомфортно для нормального человека. В 2007 году была предложена универсальная архитектура для вычислительных устройств (CUDA) на базе видеокарт. Это позволило экстенсивно наращивать мощность устройств, сохраняя при этом основные особенности архитектуры. То есть количество процессоров и объём памяти постоянно растут, а вот разделение памяти на shared/global/texture и регистры так и сохраняются ещё с тех давних времён (с СС 2.0 появились также surface и пара кэшей, но это уже другая песня).
Однако ничто не стоит на месте и архитектура и набор команд со временем изменяются – иногда значительно, иногда не очень. Вот для отображения семейств GPU с идентичной архитектурой и были определены версии Compute сapability (СС). Для примера: устройства с CC 1.0 не умели делать атомарных операций вообще, с СС 1.1 – умели в глобальной памяти а с СС 1.2 – и в глобальной и в shared. Полный список возможностей разных СС традиционно приводится в конце CUDA C Programming Guide.
Что принесёт нам Kepler?
Во-первых – новый огромный мультипроцессор. Если раньше мультипроцессоры имели 8 (CC 1.x), 32 (CC 2.0) или 48 (СС 2.1) потоковых процессоров, то в Kepler используется новый чип на 192 процессора. Остальные характеристики тоже впечатляют:
FERMI GF100 | FERMI GF104 | KEPLER GK104 | KEPLER GK110 | |
---|---|---|---|---|
Версия CC | 2.0 | 2.1 | 3.0 | 3.5 |
Потоков в Warp'e | 32 | 32 | 32 | 32 |
Число warp'ов на мультипроцессор | 48 | 48 | 64 | 64 |
Потоков на мультипроцессор | 1536 | 1536 | 2048 | 2048 |
Блоков на мультипроцессор | 8 | 8 | 16 | 16 |
32-битные регистры на мультипроцессор | 32768 | 32768 | 65536 | 65536 |
Максимальное количество регистров/поток | 63 | 63 | 63 | 255 |
Конфигурации количества shared-памяти | 16К 48К |
16К 48К |
16К 32К 48К |
16К 32К 48К |
Максимальный размер grid по оси X | 2^16‐1 | 2^16‐1 | 2^16‐1 | 2^32‐1 |
Hyper‐Q | Нет | Нет | Нет | Есть |
Динамический параллелизм | Нет | Нет | Нет | Есть |
Какие выводы можно сделать из этой таблички? Размер warp'а остался тем же, и это – гуд. Главное, чего я опасался – это увеличение размера варпа, что привело бы к лишним простоям при ветвлениях. Но не всё так радужно. С регистрами теперь нужно быть ещё аккуратнее – чтобы максимально загрузить SMX (по количеству одновременно загруженных блоков/потоков) их нужно использовать ещё меньше… С другой стороны, архитектура позволяет хранить до 255 регистров на поток и если раньше железно работал постулат «лучше заново вычислить, чем хранить», то сейчас не всё так однозначно. Таким образом у нас появилась ещё одна вилка в пути оптимизации – можно хранить результаты вычислений в потоке, но тогда на SMX поместится меньше блоков и вполне возможно будут наблюдаться простои на чтения/запись в RAM.
Можно ещё вскользь заметить, что вычисления двойной точности и спец. функции (sin, cos и тд) теперь будут выполняться быстрее и это радует.
Второе заметное нововведение – новый Warp Scheduler. На каждый мультипроцессор приходятся 4 скедулера и каждый из них умеет исполнять 2 инструкции варпа за такт. Короче, интересная штучка. Следите, чтобы внутри варпа ветвления шли максимум по 2 путям)
Дальше непонятные штуки:
Dynamic Parallelism – вааще не понял как это будет работать, но похоже потоки смогут запускать новые grid'ы… Посмотрим, как оно будет. Похоже скоро на хосте будет только I/O, а всё остальное можно будет и на GPU запускать, раз уж есть возможность управлять kernel'ами.
GPUDirect – теперь можно взять и перекинуть данные с одной GPU на другую напрямую, без хоста. И даже по сети. Пока не увижу – не поверю. Звучит слишком круто.
Всякие приятные мелочи:
- Shuffle Instruction – новый способ обмена данными между потоками в блоке. Если лень выделять отдельную shared mem и управлять доступом к ней, то берём локальную переменную и жонглируем ей от потока к потоку.
- Атомарные операции с двойной точностью. Ну, добавили парочку. Главное – обещают ускорение до 9 раз!
- Новый read only кэш данных. В Fermi появились L1 и L2 кэши данных, а в Kepler можно отмечать данные как read only (
const __restrict
), чтобы компилятор запихивал их в этот новый кэш. А раньше я для этого данные в текстурки запихивал. Эх.
- Улучшили L2 кэш. Во-первых, он стал в 2 раза больше, а во-вторых, доступ к нему в 2 раза быстрее.
- Hyper‐Q, Grid Management Unit – в Fermi появилась возможность запускать несколько задач одновременно. А вот эти 2 технологии позволяют делать это правильно, но работают они на аппаратном уровне и мы это заметим только из более полной загрузки GPU.
И наконец, очень классное – nVidia продали души пары инженеров богам энергопотребления и теперь GTX 680 обещает кушать меньше чем аналогичная Fermi из расчёта W/FLOPS. Ну ведь круто, а? Прям хоть выкидывай старые 280 ПЕЧки. А то греются до 130 градусов и про запас на них 1,5 кВт пришлось выделять.
Вывод
Короче, не знаю как вы, а я прям с нетерпением буду ждать новых Kepler! Только не знаю, удастся ли добраться до двух компов с GPU СС 3.5 – чтоб GPUDirect пощупать. Если будет у кого – дайте потрогать, ладно?
Автор: KoppeKTop