Як блоки / основи / нитки CUDA відображаються на ядрах CUDA?


142

Я використовую CUDA вже кілька тижнів, але у мене є сумніви щодо розподілу блоків / деформацій / ниток. Я вивчаю архітектуру з дидактичної точки зору (університетський проект), тому досягнення пікових показників не викликає мого занепокоєння.

Перш за все, я хотів би зрозуміти, чи зрозуміли я ці факти:

  1. Програміст пише ядро ​​і організовує його виконання в сітці ниткових блоків.

  2. Кожен блок присвоюється потоковому багатопроцесору (SM). Після призначення він не може перейти на інший SM.

  3. Кожен SM розбиває власні блоки на Warps (наразі з максимальним розміром 32 нитки). Усі потоки в warp виконуються одночасно на ресурсах SM.

  4. Фактичне виконання потоку виконується ядрами CUDA, що містяться в SM. Немає конкретного відображення між нитками та ядрами.

  5. Якщо основи містять 20 ниток, але в даний час доступно лише 16 ядер, основи не запускаються.

  6. З іншого боку, якщо блок містить 48 потоків, він буде розділений на 2 основи, і вони будуть виконуватися паралельно за умови наявності достатньої кількості пам'яті.

  7. Якщо потік починається на ядрі, він зупиняється для доступу до пам'яті або для тривалої операції з плаваючою точкою, його виконання може відновитись на іншому ядрі.

Чи правильно вони?

Тепер у мене є GeForce 560 Ti, тому згідно специфікацій він оснащений 8 SM, кожне з яких містить 48 ядер CUDA (384 ядра в цілому).

Моя мета - переконатися, що кожне ядро ​​архітектури виконує інструкції SAME. Припускаючи, що мій код не потребуватиме більше реєстру, ніж доступний у кожній SM, я уявляв різні підходи:

  1. Я створюю 8 блоків з 48 потоків кожен, так що кожен SM має 1 блок для виконання. У цьому випадку 48 потоків будуть виконуватися паралельно в SM (експлуатуючи всі 48 доступних для них ядер)?

  2. Чи є якась різниця, якщо я запускаю 64 блоки з 6 потоків? (Якщо припустити, що вони будуть відображені рівномірно серед SMS)

  3. Якщо я "занурюю" графічний процесор у заплановані роботи (створюючи, наприклад, 1024 блоки з 1024 потоку кожного), розумно припустити, що всі ядра будуть використовуватися в певний момент і будуть виконувати однакові обчислення (припускаючи, що потоки ніколи не затримуються)?

  4. Чи є можливість перевірити ці ситуації за допомогою профілера?

  5. Чи є посилання на цей матеріал? Я читав посібник із програмування CUDA та глави, присвячені архітектурі апаратних засобів у "Програмуванні масивно паралельних процесорів" та "Проектуванні та розробці програм CUDA"; але я не зміг отримати точної відповіді.


Я хотів би додати як коментар те, що є "ядром CUDA". "Ядро CUDA" або "Блок виконання" - це цілочисельне ціле число ALU і FPU, яке виконує одну інструкцію з арифметичної інструкції за тактовий цикл в одному куд-потоці.
bruziuz

Відповіді:


123

Дві найкращі посилання є

  1. NVIDIA Fermi Compute Architecture Whitepaper
  2. GF104 Відгуки

Я спробую відповісти на кожне ваше запитання.

Програміст ділить роботу на нитки, нитки на блоки потоків, а блоки потоків - на сітки. Розчислювач обчислювальної роботи виділяє блоки потоків потоковим мультипроцесорам (SMs). Після розподілу блоку потоку до SM, ресурси для потокового блоку розподіляються (основи та спільна пам'ять), а потоки діляться на групи з 32 потоків, які називаються основами. Після виділення основи вона називається активною основою. Два планувальника основи вибирають два активних деформації за цикл і відправляють основи до одиниць виконання. Для отримання більш докладної інформації про виконавчих пристроїв і інструкції по відправці см 1 p.7-10 і 2 .

4 ' . Існує відображення між laneid (індекс ниток у основи) та серцевиною.

5 ' . Якщо основи містять менше 32 ниток, вона в більшості випадків буде виконуватися так само, як якщо б вона мала 32 нитки. Основи можуть мати менше 32 активних потоків з кількох причин: кількість потоків на блок не ділиться на 32, програма виконує розбіжний блок, тому нитки, які не взяли поточний шлях, позначаються неактивними, або потік у warp вийшов.

6 ' . Блок потоку буде розділений на WarpsPerBlock = (ThreadsPerBlock + WarpSize - 1) / WarpSize Немає вимоги для планувальників основи вибирати два основи з одного блоку потоку.

7 ' . Блок виконання не зупиниться на операції з пам'яттю. Якщо ресурс недоступний, коли інструкція готова до відправлення, інструкція буде знову відправлена ​​в майбутньому, коли ресурс буде доступний. Основи можуть затримуватися на бар'єрах, на операціях з пам'яттю, операціях з текстурою, залежностями даних, ... Затриманий деформатор не може бути обраний планувальником деформації. У Fermi корисно мати принаймні 2 основи, що підходять для циклу, щоб планувальник основи міг видавати інструкцію.

Див. Посилання 2 щодо відмінностей між GTX480 та GTX560.

Якщо ви прочитаєте довідковий матеріал (кілька хвилин), я думаю, ви побачите, що ваша мета не має сенсу. Я спробую відповісти на ваші моменти.

1 ' . Якщо запустити ядро ​​<<< 8, 48 >>>, ви отримаєте 8 блоків з 2 основами з 32 та 16 потоків. Немає гарантії, що ці 8 блоків будуть призначені різним SM. Якщо для SM виділено 2 блоки, то, можливо, кожен планувальник основи може вибрати основу та виконати основу. Ви будете використовувати лише 32 з 48 ядер.

2 ' . Існує велика різниця між 8 блоками з 48 потоків і 64 блоками з 6 потоків. Припустимо, що ваше ядро ​​не має розбіжності, і кожен потік виконує 10 інструкцій.

  • 8 блоків з 48 нитками = 16 деформацій * 10 інструкцій = 160 інструкцій
  • 64 блоки з 6 нитками = 64 основи * 10 інструкцій = 640 інструкцій

Для досягнення оптимальної ефективності розподіл роботи повинен бути кратним 32 нитки. Обладнання не з’єднуватиме нитки з різних основ.

3 ' . GTX560 може мати 8 блоків SM * 8 = 64 блоки одночасно або 8 SM * 48 деформацій = 512 деформацій, якщо ядро ​​не збільшує максимум регістрів або спільної пам'яті. У будь-який час частина роботи буде активною на SM. Кожен SM має декілька одиниць виконання (більше ядер CUDA). Які ресурси використовуються в будь-який момент часу, залежить від основоположних планувальників та набору інструкцій програми. Якщо не робити операцій з TEX, то блоки TEX будуть простоювати. Якщо не робити спеціальних операцій з плаваючою комою, підрозділи SUFU будуть простоювати.

4 ' . Паралельне розуміння та шоу Visual Profiler

а. виконується IPC

б. видав IPC

c. активні основи на активний цикл

г. придатні основи за активний цикл (лише Nsight)

е. причини основи стійлості (лише Nsight)

f. активні потоки за виконаною інструкцією

Профілер не показує відсоток використання жодного з блоків виконання. Для GTX560 приблизною оцінкою буде IssuedIPC / MaxIPC. Для MaxIPC припустимо, що GF100 (GTX480) становить 2 GF10x (GTX560) - це 4, але ціль 3 - краща ціль.


1
Спасибі за вашу відповідь. Я читаю посилання, але є кілька речей, які я не розумію у вашій відповіді. У наступних запитаннях я припускаю, що ми використовуємо архітектуру Фермі з 48 ядрами (16 ядер * 3 "основні групи"): 1. Ви згадали відображення між ядрами та провулком. Що це за картування? 2. З посилань я дійшов до висновку, що кожна "основна група" виконує щонайбільше напівперспективу (16 потоків) за тактовий цикл. Тож теоретично, якщо ми маємо 48 ниток в одному блоці, вони будуть організовані в 3 напівскладок і будуть виконуватися паралельно на 48 ядрах. Маю рацію?
Дедал

1
Ядра CUDA - це кількість одиничних точних FP одиниць. Думка про виконання з точки зору ядер CUDA не є правильним. Кожна основа має 32 нитки. Ці потоки будуть видані до групи виконавчих одиниць (наприклад, 16 ядер куда). Для того, щоб видавати всі 48 ядер за один годинник, одному з двох планувальників основи потрібно вибрати основу, що відповідає вимозі суперскалярної пари, і обидві інструкції повинні бути типу, виконаними ядрами CUDA. Крім того, інший програміст основи повинен вибрати основу, наступна інструкція якої буде виконуватися ядрами CUDA.
Грег Сміт

1
Немає вимоги, щоб основи знаходилися в одному блоці або щоб основи в блоці мали однаковий лічильник програм.
Грег Сміт

2
У вашому прикладі кожен планувальник вибирає основу і видає 1 інструкцію. У цьому випадку будуть використовуватися лише 2 групи виконавчих одиниць. Для використання більшої кількості одиниць виконання 1 планувальник має подвоїти випуск. Як зазначено в посиланнях, існує кілька типів одиниць виконання (не тільки те, що є придуманими ядрами cuda), і існують правила спарювання інструкцій (недостатньо задокументовані), які повинні бути дотримані для планувальників подвійного випуску.
Грег Сміт

1
@GregSmith Я шукаю по всьому Інтернету, щоб дізнатися, звідки беруться ці 8 активних блоків на SM в архітектурі Fermi. Про його навіть не згадується у газеті Fermi. Чи є у вас більше посилання на це?
Грег К.

8

"E. Якщо основи містять 20 ниток, але в даний час доступно лише 16 ядер, основи не запускаються."

невірно. Ви плутаєте сердечники в їх звичайному розумінні (також використовуються в процесорах) - кількість "багатопроцесорів" в графічному процесорі, з ядрами в nVIDIA маркетингу говорять ("наша карта має тисячі ядер CUDA").

Саму основу можна запланувати лише на одному ядрі (= багатопроцесорний) і може запускати до 32 потоків одночасно; він не може використовувати більше одного ядра.

Число "48 деформацій" - це максимальна кількість активних деформацій (основи, які можуть бути обрані для планування роботи в наступному циклі, в будь-якому даному циклі) на багатопроцесор, на nVIDIA GPU з обчислювальною здатністю 2.x; і це число відповідає 1536 = 48 х 32 ниток.

Відповідь на основі цього вебінару


@GregSmith: Редагував відповідь, щоб вирішити цю проблему. Добре, що ви були терплячими, але - минуло п'ять років ...
einpoklum

одноядерний (= багатопроцесорний)? Я думаю, що питання передбачає термінологію одноядерний = процесор, а не багатопроцесорний. З термінологією ваша відповідь правильна.
Adarsh
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.