Чи можливо в програмуванні програмного забезпечення мати навантаження на процесор і GPU на 100%?


43

Це загальне питання на тему, що мені було цікаво як геймер: вузькі місця CPU / GPU та програмування. Якщо я не помиляюсь, я зрозумів, що і CPU, і GPU обчислюють речі, але в деяких розрахунках один кращий, ніж інший через різницю в архітектурі. Наприклад, крекінг хешей або видобуток криптовалют здається набагато ефективнішим для графічних процесорів, ніж для процесорів.

Тому я задумався: неминуче використання графічного процесора на 100% завантаженні, тоді як процесор знаходиться на 50% (наприклад)?

Або, точніше: чи можуть деякі обчислення, які зазвичай виконує GPU, виконані процесором, якщо перший із 100% завантаженням, щоб обидва досягали 100% навантаження?

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


53
Тривіально можливо, щоб і CPU, і GPU одночасно виконували нескінченний цикл NO-OPs, що призведе до того, що обоє мають навантаження 100%.
Йорг W Міттаг

17
На думку @ Джорга, єдине, що вимірюється% процесора, - це те, що частина часу не витрачається на очікування інших процесорів. 100% може бути хорошою справою, якщо програма ефективна, або погана, якщо програма неефективна. Занадто багато часу люди зосереджуються на відсотках процесора, ніби це показник продуктивності - це не так.
Майк Данлаве

22
Оригінальний Crysis зробив це просто чудово.
CubicleSoft

5
@MikeDunlavey ви підкреслили хороший момент. З автомобілями ми не вимірюємо їх ефективність обертів, ми вимірюємо швидкість.
Людина капітана

1
@ JörgWMittag: Процесор, можливо. Але ОС і графічні процесори зупиняють вирішення проблем для вирішення нескінченних циклів. А саме, якщо шейдер не завершиться за розумну кількість часу, він загине, і GPU скидається.
Ніколь Болас

Відповіді:


62

Теоретично так, але практично це рідко варто.

І CPU, і GPU є завершеними , тому будь-який алгоритм, який може бути обчислений одним, також може бути обчислений іншим. Питання в тому, наскільки швидко і наскільки зручно.

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

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


1
Ви згадали, що з більшості проблем різниця в продуктивності між процесорами та реалізацією GPU величезна , я насправді дуже зацікавлений, в якій мірі йде розбіжність у продуктивності. Чи були б у вас якісь цифри чи статті щодо цього (наприклад, на прикладі текстурного 3D-рендерінгу)? Дякуємо за вашу відповідь та за ваш час!
MadWard

2
Ви можете додати, що для синхронізації між процесором та графічним процесором існують витрати на продуктивність, тому, як правило, ви хочете мінімізувати кількість передач між ними. Крім того, наївно додавання у гілки для "не виконувати елементи, над якими вже працював процесор" нічого не купить вам, оскільки потоки GPU працюють у режимі блокування.
Етан

3
@gardenhead Ніщо у Всесвіті не підтримує необмежену рекурсію, оскільки Всесвіт має обмежений розмір і має кінцеву щільність інформації. "Тюрінг-повнота" системи - це загалом обговорення того, що було б можливо при усуненні таких обмежень.
Випадково832

3
Я не сумніваюся, що сучасний GPU технічно як мінімум наближений до повноти Тьюрінга, як і ПК 80-х… Однак, якщо ви спробуєте запустити загальні алгоритми на графічному процесорі, він зазвичай перероджується в послідовний процесор, який також не буде швидше, ніж ПК 80-х, тож повнота Тьюрінга GPU на практиці навряд чи корисніша, ніж повнота Тьюрінга Brainfuck .
близько

7
@leftaroundabout Сучасні GPU тривіально завершуються як будь-який процесор . Завершення повноти не має нічого спільного з: 1) продуктивністю 2) читабельністю джерела. Процесор 80-х був настільки ж близьким до TC, що і все інше: або вони були TC, або їх не було (останній варіант - це нісенітниця).
Маргарет Блум

36

Це не пов’язано з ігровим програмуванням. Деякий науковий код також може використовувати як GPU, так і процесор.

При уважному та болісному програмуванні, наприклад, використовуючи OpenCL або CUDA , ви можете завантажити і ваш GPU, і ваш процесор майже на 100%. Ймовірно, вам потрібно буде написати різні фрагменти коду для GPU (так званий "код ядра") і для процесора, і якийсь нудний код клею (зокрема, щоб надіслати в GPU скомпільований код ядра).

Однак код буде складним, і вам, ймовірно, потрібно налаштувати його на конкретне обладнання, на якому ви працюєте, зокрема, тому що передача даних між GPU та процесором дорога.

Детальніше про неоднорідні обчислення .

Дивіться також OpenACC , підтримуваний останніми версіями GCC (наприклад, GCC 6 у червні 2016 року)


1
Ви маєте рацію, мої теги та назва вводили в оману, видаляли ігри та додавали продуктивність / оптимізацію. Я не мав на увазі, що це виключно для ігор, але саме там я це помітив. Я думав, що це теж повинно бути дуже специфічним для обладнання. Дякуємо за вашу відповідь та посилання!
MadWard

3
Це майже би закінчилося двома алгоритмами. Я спробував це один раз: ціле зображення одразу для GPU і кілька зображень одночасно для процесора (зловживати великим кешем). Це справді боляче, особливо підтримувати.
PTwr

11

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

Якщо ви отримуєте 100% використання процесора, це не обов'язково означає, що ви отримуєте всі продуктивність системи. Процесори часто можуть одночасно робити різні речі, скажімо, поділ та доповнення. Якщо ви можете розпочати поділ рано, можливо, це може бути перекрито додаванням. Швидше за все, на вашому настільному процесорі є блок поза замовлення, який буде впорядковувати заяви, щоб отримати користь від таких перекриттів. Або якщо у вас є така програма:

if (expr1)
    expr2;
else
    expr3;

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

Потім у вас є функції SIMD в процесорах, які є векторними операціями. Це як GPGPU-світло в тому сенсі, що зазвичай у вас є одночасно лише чотири-вісім операцій, GPU - це як 32 або 64. Тим не менш, ви повинні використовувати це, щоб викрутити FLOPS.

Такі речі, як помилковий обмін, можуть призвести до великої вартості синхронізації, яка зазвичай виявляється завантаженням ядра в Linux. Процесор повністю використовується, але у вас не дуже корисна пропускна здатність.

Я кілька програмував на машині IBM Blue Gene / Q. Він має багато рівнів ієрархії ( схема застарілої Blue Gene / L ), і тому важко ефективно програмувати. Вам доведеться використовувати повну ієрархію до SIMD та SMT (Intel називає це HyperThreading), щоб отримати продуктивність.

І тоді мережа часто вас обмежує. Тому виявляється, що швидше (настінний годинник) обчислювати речі в декількох процесорах одночасно, а не спілкуватися по мережі. Це дасть більше навантаження на процесори та змусить програму працювати швидше. Але реальна пропускна здатність програми не настільки хороша, як це здається із вихідних чисел.

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


1

Можливо, вам буде цікаво перевірити механізм браузера Servo, який розробляється в Mozilla Research, а точніше його веб-рендерінг (відео) .

Хоча динамічне перенесення завдання з процесора на GPU динамічно може бути недоцільним, як це зазначається в інших відповідях (зокрема @ Philip's), можна заздалегідь вивчити навантаження CPU / GPU на типових робочих навантаженнях і переключити деякі завдання на загалом менш завантажені один.

Що стосується веб-рендеру, новинка полягає в тому, що традиційно браузери виконують більшу частину своєї роботи по рендерингу на процесорі (тобто ЦП використовується для обчислення, які об’єкти відображати, де вирізати тощо). Графічний процесор, як правило, краще в ньому ... за винятком того, що не всі сфери використання є тривіальними для реалізації (часткове вилучення, тіні, ... та текст).

Початкова версія веб-рендеру виявилася дуже успішною у збільшенні продуктивності, але не намагалася вирішити проблему візуалізації тексту (і мала деякі інші обмеження). Зараз Mozilla Research працює над другою версією, яка повинна мати менші обмеження, а саме для підтримки надання тексту.

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

Таким чином, хоча і не настільки крайніх , як вашу пропозицію, він дійсно йде в напрямку розробки стратегії обчислень з обох CPU і GPU на увазі.


0

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

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

Однак теоретично ви можете динамічно переключатися між тим, як робити це на процесорі чи графічному процесорі, залежно від того, наскільки перевантажені процесор і процесор.

Основним блокатором цього для всіх розрахунків є те, що процесор і GPU мають різні сильні та слабкі сторони. Масово паралельні завдання краще виконувати на GPU, тоді як інтенсивні лінійні завдання з розгалуженням краще виконувати на процесорі. Лише декілька робіт можна було б реально виконати на обох без серйозних результатів.

Загалом, головна проблема програмування GPU (принаймні, з OpenGL та DirectX 11 і нижче) полягає в тому, що ви мало контролюєте, як GPU інтерпретує ваш шейдерний код. Розгалуження всередині шейдера є ризикованим, тому що якщо ви випадково створили залежність між обчисленнями, то GPU може вирішити почати візуалізацію ваших пікселів один за одним, перетворюючи 60 кадрів в секунду в 10 кадрів в секунду, незважаючи на те, що фактичні дані мають бути однаковими.


0

Одним із реальних прикладів є двигун візуалізації з відкритим кодом LuxRender , який здатний одночасно завантажувати CPU та GPU. Крім того, він може завантажувати декілька графічних процесорів одночасно, а також може поширюватись на декілька комп'ютерів.

LuxRender використовує OpenCL для полегшення цього, хоча складання без OpenCL також існують.

Це практично, оскільки алгоритми, які використовує LuxRender, є дуже паралельними. Найпоширеніший алгоритм, який використовує LuxRender, - це відстеження траєкторій , де багато індивідуальних легких шляхів можна обчислювати незалежно один від одного - ідеальна ситуація для обчислення GPU і така, яка не потребує складної синхронізації між обчислювальними вузлами. Однак обмеження графічних процесорів (менший об'єм пам'яті, відсутність підтримки деяких складних функцій візуалізації та загальна відсутність доступності для деяких виконавців) гарантують, що підтримка процесора все ще є важливою.


який сенс показу цього зображення, наскільки це стосується заданого питання?
гнат

1
Е-чудово. Я його видалю. Я думав, що це легко продемонструє, що це за програмне забезпечення. Але, можливо, це просто насправді відволікає. (Існує багато різних видів рендерингу; цей орієнтований на фотореалістичні фотографії.)
PythonNut

0

Так, це, безумовно, можливо.

Будь-які обчислення, які може виконати процесор, також може робити і графічний процесор, і навпаки.

Але це нечасто, тому що:

  • Інженерна складність Хоча можна запускати один і той же код на процесорі та графічному процесорі (наприклад, CUDA), процесори мають різні здібності та характеристики продуктивності. Один - MIMD; інший, SIMD. Те, що швидко відбувається на одному, повільно, а на іншому (наприклад, розгалуження), тому вам потрібно написати окремий код для досягнення максимальної продуктивності.

  • Ефективність витрат графічних процесорів в сукупності багато могутніше процесорів. Вся ідея графічних процесорів полягає у використанні дешевших, повільніших, але більш численних процесорів для виконання обчислень, набагато швидших, ніж процесори могли за ту саму ціну. Графічні процесори ефективніше витрачаються на один або два порядки.

Якщо у вас є алгоритм для роботи на графічних процесорах, це просто більше сенсу оптимізувати для них і додати стільки, скільки вам потрібно.

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