OpenGL проти OpenCL, який вибрати і чому?


78

Які особливості роблять OpenCL унікальним для вибору серед OpenGL із GLSL для розрахунків? Незважаючи на графічну термінологію та непрактичні типи даних, чи існує реальне застереження до OpenGL?

Наприклад, паралельна оцінка функції може бути виконана шляхом надання а текстурі за допомогою інших текстур. Зменшувальні операції можна виконати шляхом ітераційного відтворення до дедалі менших текстур. З іншого боку, випадковий доступ до запису неможливий будь-яким ефективним способом (єдиний спосіб зробити це рендерінг трикутників за допомогою текстурованих вершинних даних). Чи можливо це з OpenCL? Що ще можливо, неможливо з OpenGL?


1
Іншим цікавим питанням було б, якщо OpenGL може запропонувати щось, чого OpenCL не може. Наприклад, OpenGL автоматично інтерполює varyingдля вас дані вершин, які були оголошені ключовим словом. Як би ви досягли відповідної речі в OpenCL?
HelloGoodbye

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

1
У нас 2015 рік, досі немає надійного доступу до OpenCL на всіх платформах, все ще цікаво, якої якості обчислень можна досягти OpenCL, але не OpenGL2.0.
дронус

1) Пристрій OpenCL може бути процесором, без будь-якого процесора, і все ще працює там, де візуалізація графіки взагалі не працює.
xakepp35

2) Поміркуйте, який стек тонший, наприклад, на ядрі barebone linux? OpenCL, який вимагає лише такої простої речі, як драйвер, amdgpu-pro, що постачається з усіма необхідними бібліотеками (я зробив прошивку для майнера OpenCL із розміром лише 50 Мб). Або візуалізатор (150 + mb), який вимагає більше возитися, кілька важких фреймворків, ксоргів тощо, і все робиться як всередині mesa3d / gallium тощо. для чого це все? якщо ваше завдання полягає лише в обчисленні, а у вас немає запущеного x-сервера і навіть не підключений монітор. отже, в основному, GL є більш "перевантаженим", ніж CL, для того, щоб підтримати все і все, що розроблялося роками.
xakepp35

Відповіді:


62

OpenCL створений спеціально для обчислень. Коли ви робите наукові обчислення за допомогою OpenGL, вам завжди потрібно думати про те, як відобразити вашу обчислювальну проблему до графічного контексту (тобто говорити з точки зору текстур та геометричних примітивів, таких як трикутники тощо), щоб розпочати обчислення.

У OpenCL ви просто формулюєте свої обчислення за допомогою ядра обчислення в буфері пам'яті, і все готово. Це насправді ВЕЛИКИЙ виграш (кажучи, що з точки зору продумування та реалізації обох варіантів).

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

Але що ще ви очікуєте, ніж використання більше десятка паралельних "процесорів", не розбиваючи голови про те, як перекладати - наприклад (дурний приклад) Фур'є до трикутників і квадратиків ...?


1
Фур'є до трикутників і квадратиків ... а за допомогою простого ешафоту рендеринга одного великого квадратику на текстуру ми просто маємо просте паралельне відображення одного або декількох великих блоків пам'яті в інший. З текстурами різного масштабу також легко перенести різну кількість (зазвичай 2 ^ n) значень на іншу. Це не надто багато коду GL та відповідає великій кількості проблем. Тому мені подобається знати, що OpenCL може зробити більше ...
dronus

2
Використовуючи OpenCL, ви просто повністю опускаєте відображення, уникаєте написання шейдерів, які повинні мати справу з геометрією та фрагментами, уникаєте думок про різне перетворення координат (світ, екран / буфер, текстура) і безпосередньо виражаєте свій алгоритм, як ви дізналися у своєму клас чисельності. У мене не було проблем з першим, але як із останнім більше. І добре, я спочатку не придумував ідею OpenCL - але як хтось інший, чому не слід використовувати її за призначенням? GPGPU на даний момент був крутий, тепер просто використовуйте OpenCL.
cli_hlt

7
@cli_hlt, OpenCL також є GPGPU.
Саймон

@Simon У широкому розумінні, так, ти маєш рацію. Але, згідно з Вікіпедією, "Обчислення загального призначення на одиницях обробки графіки (GPGPU, рідше GPGP або GP²U) - це використання пристрою обробки графіки (GPU), який зазвичай обробляє обчислення лише для комп'ютерної графіки, для обчислення в додатках, які традиційно обробляються центральним процесорним блоком (ЦП) "(у них є додаткові посилання, які я зараз опускаю). З OpenCL більше не наводиться суть "що зазвичай обробляє обчислення лише для комп'ютерної графіки". Тож це не GPGPU у початковому значенні.
cli_hlt

@cli_hlt: Можливо, але пристрої все-таки призначені в першу чергу для комп'ютерної графіки. Зрештою, їх все ще називають графічними процесорами!
Tim Čas

54

Щось, про що досі не згадувалося в жодних відповідях, це швидкість виконання. Якщо ваш алгоритм може бути виражений графікою OpenGL (наприклад, відсутність розсіяних записів, відсутність локальної пам'яті, робочих груп тощо), він дуже часто буде працювати швидше, ніж аналог OpenCL. Мій конкретний досвід у цій роботі полягає у фільтруванні (збиранні) ядер у графічних процесорах AMD, nVidia, IMG та Qualcomm. Реалізації OpenGL незмінно працюють швидше навіть після жорсткої оптимізації ядра OpenCL. (крім: я підозрюю, що це пов’язано з роками роботи апаратного забезпечення та драйверів, спеціально налаштованих на графічне навантаження.)

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

Ще один момент, про який слід згадати (або запитати) - чи пишете ви як любитель (тобто для себе) чи комерційно (тобто для розповсюдження серед інших). Хоча OpenGL підтримується майже скрізь, OpenCL повністю не має підтримки на мобільних пристроях, і, на жаль, навряд чи він з'явиться на Android або iOS протягом найближчих кількох років. Якщо метою є широка сумісність між платформами з однієї бази коду, то OpenGL може бути нав'язаний вам.


Я думаю, що для цієї відповіді дійсно потрібно більше голосів, щоб вони з’явилися раніше в цій темі. Міркування щодо продуктивності та сумісності мобільних пристроїв повинні бути найважливішими аспектами, які слід врахувати спочатку ... принаймні міркування щодо продуктивності, якщо ви не зацікавлені у мобільних пристроях (але сьогодні, як ви не можете, чи, точніше, як ви можете собі дозволити цього не робити? : p)
військовий корабель

Як OpenGL може бути швидшим за OpenCL? Це робить набагато більше, і накладні витрати на управління станом OpenGL високі. Ви порівнювали з OpenCL із функціями native_ *? Які операції ви порівнювали? Чи можете ви опублікувати код?
Йоав,

2
Привіт Бен-Урі. На жаль, я не можу поділитися кодом. Ви маєте рацію щодо того, що стан GL є досить важким, але добре написаний код GL може здебільшого уникати змін стану, особливо для обчислювальних завдань (Вулкан у цьому відношенні набагато кращий). Окремі операції, як правило, приблизно однакові між GL / CL, але компілятори GLSL здаються більш зрілими і створюють загальний жорсткий код. Крім того, для структурованих записів, піксельні шейдери GL можуть використовувати одиниці виводу візуалізації (ROP), тоді як CL повинен використовувати загальну підсистему пам'яті (повільніше), оскільки вона (зазвичай) не може бути відома під час компіляції, якщо записи будуть структуровані.
user2746401

27

Які особливості роблять OpenCL унікальним для вибору серед OpenGL із GLSL для розрахунків? Незважаючи на графічну термінологію та непрактичні типи даних, чи існує реальне застереження до OpenGL?

Так: це графічний API. Тому все, що ви робите в ньому, має бути сформульовано відповідно до цих термінів. Ви повинні упакувати свої дані як певну форму "візуалізації". Ви повинні зрозуміти, як поводитися з вашими даними з точки зору атрибутів, єдиних буферів та текстур.

З обчислювальними шейдерами OpenGL 4.3 та OpenGL ES 3.1 все стає дещо заплутанішим. Шейдер обчислень може отримувати доступ до пам'яті через SSBOs / Image Load / Store аналогічно обчислювальним операціям OpenCL (хоча OpenCL пропонує фактичні вказівники, тоді як GLSL цього не робить). Їх взаємодія з OpenGL також набагато швидша, ніж взаємодія OpenCL / GL.

Незважаючи на це, обчислювальні шейдери не змінюють одного факту: обчислювальні операції OpenCL працюють з абсолютно різною точністю, ніж обчислювальні шейдери OpenGL. Вимоги до точності з плаваючою комою GLSL не дуже жорсткі, а OpenGL ES ще менш жорсткі. Отже, якщо точність з плаваючою точкою є важливою для ваших розрахунків, OpenGL не буде найефективнішим способом обчислення того, що вам потрібно обчислити.

Крім того, для обчислювальних шейдерів OpenGL потрібно апаратне забезпечення, що підтримує 4.x, тоді як OpenCL може працювати на значно гіршому апаратному забезпеченні.

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

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

OpenCL не є графічним API; це обчислювальний API.

Крім того, OpenCL просто надає вам доступ до більшої кількості матеріалів. Це дає вам доступ до рівнів пам'яті, які неявно стосуються GL. Певна пам'ять може бути спільно використана між потоками, але окремі екземпляри шейдерів у GL не можуть впливати безпосередньо один на одного (поза Image Load / Store, але OpenCL працює на обладнанні, яке не має до нього доступу).

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

Ви можете використовувати OpenGL для довільних обчислень. Але ти не хочеш ; не поки є цілком життєздатна альтернатива. Обчислення в OpenGL діє для обслуговування графічного конвеєру.

Тільки причина , щоб вибрати OpenGL для будь-якого виду НЕ-рендеринга операції обчислювальному є підтримка апаратних засобів , які не можуть працювати OpenCL. В даний час сюди входить багато мобільного обладнання.


6
'OpenGL приховує те, що робить обладнання, за абстракцією. OpenCL піддає вас майже точно тому, що відбувається '. я все ще на абстрактному рівні, я думаю. Графічні процесори мають фіксовані модулі (наприклад, `` Рендери вихідних одиниць '' та `` Одиниці відображення текстур ''), виражені в функціях OpenGL.
дронус

1
@ybungalobill Згідно з описом glTexImage2D, "ГЛ вибере внутрішнє подання, яке наближається до того, що запитується внутрішнім Форматом , але воно може не точно відповідати".
GuyRT

1
@GuyRT: Зазвичай це дає 32F для 32F --- типова зміна - це інший порядок каналів (наприклад, BGRA замість RGBA).
Tim Čas

Ця відповідь стосується "OpenGL / GSLS" чи просто OpenGL?
wotanii

1
@wotanii: GLSL - це мова затінення, що використовується OpenGL. Тож не існує "просто OpenGL".
Nicol Bolas

12

Однією помітною особливістю буде розсіяність записів, іншою - відсутність "розумності Windows 7". Як ви, мабуть, знаєте, Windows 7 вб'є драйвер дисплея, якщо OpenGL не змине приблизно 2 секунди (не забивайте мені точний час, але я думаю, що це 2 секунди). Це може дратувати, якщо у вас тривала операція.

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


+1 для згадування розсіювання, хоча нещодавні розширення (наприклад shader_image_load_store) працюють над цим, або ви можете використовувати шейдер геометрії для створення додаткових точок або вибору різних вихідних цілей. Але нічого в порівнянні з гнучкістю OpenCL.
Крістіан Рау

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

2
@cli_hlt: Ви заздалегідь вирішите, на якому пристрої будуть працювати ваші черги завдань (а отже, ядра). Реалізація не має можливості вирішити щось інше пізніше. Крім того, такі функції, як розсіяна запис або локальна пам’ять, не є чимось «особливим», що апаратне забезпечення підтримує або не підтримує. Просто під OpenGL одне і те ж обладнання його не виставлятиме, оскільки OpenGL реалізує графічний конвеєр. Таким чином, просто немає сенсу підтримувати запис у локальну пам’ять у піксельному шейдері (і «історичне» обладнання справді не могло цього зробити). Під OpenCL це має сенс і дозволено.
Деймон

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

1
Ви знаєте, що ОС теж вб'є драйвер, якщо OpenCL робить тривалий розрахунок на графічному процесорі?
Тара

11

Хоча в даний час OpenGL буде кращим вибором для графіки, це не постійно.

Для OpenGL може бути практичним з часом об’єднатись як розширення OpenCL. Ці дві платформи приблизно на 80% однакові, але мають різні синтаксичні хитрощі, різну номенклатуру приблизно однакових компонентів обладнання. Це означає дві мови для вивчення, два API для з’ясування. Розробники графічних драйверів воліють об’єднання, оскільки їм більше не доведеться розробляти дві окремі платформи. Це залишає більше часу та ресурсів для налагодження драйверів. ;)

Інша річ, яку слід врахувати, полягає в тому, що походження OpenGL та OpenCL різне: OpenGL почав та набирав обертів у перші дні фіксованого конвеєру над мережею, і повільно додавався та припинявся у міру розвитку технології. OpenCL, в деякому сенсі, це еволюція в OpenGL в тому сенсі , що OpenGL почав використовуватися для цифрової обробки , як (незаплановані) гнучкість графічних процесорів дозволило так. "Графіка проти обчислень" насправді є більше семантичним аргументом. В обох випадках ви завжди намагаєтеся зіставити свої математичні операції з апаратним забезпеченням з максимально можливою продуктивністю. Є частини апаратного забезпечення графічного процесора, які ванільний CL не використовуватиме, але це не буде перешкоджати цьому робити окреме розширення.

То як OpenGL може працювати під CL? Спекулятивно, рослини-трикутники можна поставити в чергу як спеціальне завдання CL. Спеціальні функції GLSL можуть бути реалізовані у ванільному OpenCL, а потім замінені на апаратно прискорені інструкції драйвером під час компіляції ядра. Написання шейдера в OpenCL, очікуючи на розширення бібліотеки, зовсім не звучить болісно.

Називати одного, щоб мати більше функцій, ніж інший, не має особливого сенсу, оскільки вони обидва отримують на 80% однакові функції, просто під різною номенклатурою. Стверджувати, що OpenCL не годиться для графіки, оскільки вона призначена для обчислень, не має сенсу, оскільки обробка графіки - це обчислення.


6

Інша основна причина полягає в тому, що OpenGL \ GLSL підтримуються лише на відеокартах. Незважаючи на те, що багатоядерне використання почалося з використання графічного обладнання, багато постачальників обладнання працюють на багатоядерній апаратній платформі, націленій на обчислення. Наприклад, див. Intels Knights Corner.

Розробка коду для обчислень за допомогою OpenGL \ GLSL не дозволить вам використовувати будь-яке обладнання, яке не є графічною картою.


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

4

Ну а щодо OpenGL 4.5 це ті функції, які OpenCL 2.0 має, що OpenGL 4.5 цього не робить (наскільки я міг сказати) (це не охоплює тих функцій, які OpenGL має, а OpenCL - ні):

Події

Краща атоміка

Блоки

Функції робочої групи: work_group_all та work_group_any work_group_broadcast: work_group_reduce work_group_inclusive / exclusive_scan

Виділити ядро ​​з ядра

Покажчики (хоча, якщо ви виконуєте на графічному процесорі, це, мабуть, не має значення)

Кілька математичних функцій, яких OpenGL не має (хоча їх можна створити самостійно в OpenGL)

Спільна віртуальна пам’ять

(Докладніше) Параметри компілятора для ядер

Легко вибрати певний графічний процесор (або іншим способом)

Може працювати на центральному процесорі, коли немає графічного процесора

Більша підтримка тих нішових апаратних платформ (наприклад, FGPA)

На деяких (усіх?) Платформах для обчислення вам не потрібне вікно (та його прив’язка до контексту).

OpenCL дозволяє трохи більше контролювати точність обчислень (включаючи деякі через ці параметри компілятора).

Багато з перерахованого здебільшого стосується кращої взаємодії процесора та графічного процесора: події, спільна віртуальна пам’ять, покажчики (хоча це може також принести користь іншим речам).

OpenGL отримав можливість сортувати речі за різними областями пам’яті клієнта та сервера, оскільки було зроблено багато інших публікацій. Зараз OpenGL має кращий бар’єр пам’яті та підтримку атомів і дозволяє розподіляти речі між різними регістрами в графічному процесорі (приблизно в однаковій мірі може OpenCL). Наприклад, ви можете спільно використовувати регістри в локальній групі обчислень зараз у OpenGL (використовуючи щось на зразок графічних процесорів AMD LDS (локальний обмін даними) (хоча ця особливість у цей час працює лише з обчислювальними шейдерами OpenGL). деякі платформи (наприклад, драйвери з відкритим кодом Linux). OpenGL має доступ до апаратного забезпечення з більш фіксованою функцією (як сказано в інших відповідях). Хоча це правда, що іноді апаратного забезпечення з фіксованою функцією можна уникнути (наприклад, Crytek використовує "програмне забезпечення" реалізація буфера глибини) апаратне забезпечення з фіксованою функцією може чудово управляти пам'яттю (і, як правило, набагато краще, ніж хтось, хто не працює в апаратній компанії GPU), і в більшості випадків просто значно перевершує. Я повинен визнати, що OpenCL має досить хорошу підтримку текстур фіксованих функцій, що є однією з основних областей фіксованої функції OpenGL.

Я стверджую, що Intels Knights Corner - це графічний процесор x86, який контролює себе. Я також міг би стверджувати, що OpenCL 2.0 з його текстурними функціями (які насправді є в менших версіях OpenCL) можуть бути використані приблизно з тим самим ступенем продуктивності, який пропонував user2746401.


3

OpenCL (у версії 2.0) описує неоднорідне обчислювальне середовище, де кожен компонент системи може як виробляти, так і споживати завдання, генеровані іншими системними компонентами. Більше не потрібно понять CPU, GPU (тощо) - у вас є лише Host & Device (s).

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


2

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

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

Після того, як ви зробите щось більш складне, ніж прості підпрограми BLAS рівня 1, ви, безсумнівно, оціните гнучкість та загальність OpenCL / CUDA.


1
Я не впевнений у тому, "але також не занадто абстрагує базове обладнання". Здається, OpenCL насправді буде повністю ігнорувати частини апаратного забезпечення, наприклад одиниці растеризації.
дронус

@dronus Ну, так, він ігнорує частини з фіксованою функцією. Але з іншого боку шейдери абстрагують багатоядерну природу обладнання та такі речі, як різні типи пам'яті та оптимізований доступ до пам'яті.
Крістіан Рау

1
Растеризація навіть дає можливість довільного доступу до пам'яті (до "трикутно з'єднаних" областей ...) з гарантованим результатом (фрагменти, перезаписані впорядковані по глибині z). Думаючи про ядра та потоки пам’яті, емуляція такої поведінки означала б довільний доступ із чітко визначеними впорядкованими мьютексами серед усіх паралельних потоків чи щось інше. Що таке придатний OpenCL ідеом для паралельного довільного доступу, як цей?
dronus

2

"Особливість", що OpenCL призначена для загальних обчислень, тоді як OpenGL - для графіки. Ви можете робити все, що завгодно в GL (це по Тьюрінгу), але тоді ви забиваєте цвях, використовуючи ручку викрутки як молоток.

Крім того, OpenCL може працювати не тільки на графічних процесорах, але і на центральних процесорах та різних виділених прискорювачах.

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