Програми, які стверджують, що вони не є "багатоядерними"


17

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

Як це може бути? Багато програм (особливо ігор) по своїй суті використовують паралельність, а оскільки ОС відповідає за планування завдань на процесорі, то ці програми не є по суті перевагою наявних кількох ядер? Що би означало в цьому контексті «скористатися кількома ядрами»? Чи справді такі розробники забороняють планування завдань ОС і примушування спорідненості або їх власне планування? (Звучить як головне питання стабільності).

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


11
Велика можливість полягає в тому, що в синхронізації були прийняті ярлики, які працюють для однопроцесорної / ядерної системи, але розриваються з справжньою паралельністю декількох процесорів / ядер.
Барт ван Інген Шенау

@BartvanIngenSchenau: Це правильно. Ви повинні розгорнути це та опублікувати як відповідь. Я думаю, що всі інші пропустили справу.
Кевін Клайн

1
Я думаю, що @Bart дійсно близько. Однак s / work /, здається, працює / і це буде ближче до позначки.
Ben Voigt

як осторонь - я мав досвід цього як користувач, а не програміст - Ground Control 2 у Windows XP. Мені потрібно було встановити спорідненість ядра лише до одного ядра в багатоядерній системі, щоб він працював належним чином, інакше всі анімації (в цілому вся гра) працюватимуть з 10-кратною швидкістю, яка, будучи більшою проблемою, через деякий час стає трохи дратує. . Я не робив жодної роботи над іграми, але, на мій погляд, деяка частина гри, здавалося, покладається на процесор, роблячи одночасно певну кількість роботи.
jammypeach

Відповіді:


28

Хороша паралельність вимагає набагато більше, ніж кидання кількох ниток у додаток та сподівання на найкраще. Існує діапазон того, як паралельна програма може переходити від бентежно паралельної до чистої послідовної. Будь-яка програма може використовувати закон Амдала, щоб висловити масштабність проблеми чи алгоритму. Кілька кваліфікацій для бентежно паралельної заявки будуть:

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

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

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

Існують більші архітектурні виклики в боротьбі з ефективною одночасністю

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

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

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

Суть:

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


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

8
Справжня суть полягає в тому, що вам потрібно розробити для паралельного виконання, а якщо цього не зробити, вас обмежує відсутність дизайну. Я погоджуюся, що робити різні речі паралельно може бути дуже просто, але це не так, якщо це вже наявна програма з високими сподіваннями користувачів. У цьому випадку дуже добре може знадобитися переписати, щоб це стало можливим. Переписування за своєю суттю є ризикованим, але іноді ви можете зробити хороший аргумент для них. Я зробив пару таких переписувань, які максимізували паралельну обробку, зберігаючи якомога більше коду. Там же багато прихованих чинників.
Берін Лорич

Чудова відповідь. Можливо, варто підкреслити, що при паралелізації деяких систем можливі не тільки зменшення віддачі, але й деякі можуть насправді стати повільнішими через накладні витрати, необхідні для того, щоб зробити їх паралельними. Зокрема, багато семафорів / замків та переключення контексту можуть мати несприятливий вплив на час виконання. Контекстна комутація, зокрема, може знизити ефективність кешу, що викликає нетривіальну проблему, якщо ви перебуваєте в точці оптимізації системи. Приклад OP, зокрема, ігрових двигунів, змушує мене згадати про набагато більше оптимізації кешування, ніж паралельного доступу.
Gankro

35

Багато програм (особливо ігри) по суті використовують паралельність,

Ні, насправді це навпаки. Більшість додатків написані в єдиному режимі, і розробник ніколи не вносив необхідних змін для підтримки паралельності.

У C, C ++ та C # вам потрібно чітко сказати програмі для запуску нових потоків та / або процесів.

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

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

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


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

5
@SnakeDoc - я думаю, ви там плутаєте свої домени. Компанії Big Game, безумовно, пишуть з урахуванням одночасності, але я ще не бачив гру від Big Game, яка не підтримує паралельність. Програми та ігри, які я бачив, що не можуть підтримувати паралельність, - це, як правило, з менших магазинів / окремих розробників, де вони б не починали з цього мислення. І в якийсь момент еволюції додатку стає неможливим підкріплення одночасно після факту. І деякі програми ніколи не мали на меті зробити так, щоб виправдати їх одночасність.

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

6
@SnakeDoc: Вам не потрібно паралельно працювати з тисячами екранних моделей. Це не так, як кожному об’єкту у вашій грі потрібна власна нитка, щоб імітувати її; один потік може обробляти оновлення всього екрана на кожному кроці.
user2357112 підтримує Моніку

13

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

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


8

Це не повна відповідь. Це застереження.

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

  • 14 секунд для однопотокової версії.
  • 15 секунд для 2-різьбової версії.

Це було про те, чого я очікував.

Потім я спробував це на більш новій, двоядерній машині.

  • 11 секунд для однопотокової версії.
  • 20 секунд для 2-різьбової версії.

Дві нитки розділили чергу з решти завдань. Здається, поля об’єкта черги переміщалися туди-сюди між кешем одного ядра та іншим.


2
Скільки елементів масиву ви протестували? Можливо, об'єднання було б більш придатним, оскільки багатоядерне програмування вимагало б копіювання даних, щоб уникнути конфліктів у кешовій лінії?
rwong

2
@rwong Було 10 000 000 елементів масиву. Звичайно, злиття добре паралелізувало б. Якби я використав сортування злиття, я, мабуть, не засвоїв би корисного уроку.
Теодор Норвелл

1
@ArlaudPierre Я буду розглядати паралелізацію будь-якого алгоритму. Quicksort цікавий тим, що ви можете використовувати для цього підхід "сумки завдань". Оскільки завдання незалежні, моя інтуїція полягала в тому, що це має бути прикладом бентежного паралелізму. Я мушу зазначити, що після трохи налаштування він фактично отримав швидкість, близьку до 2.
Теодор Норвелл

1
@Jules Відповідь - балансування навантаження. Також я хотів написати це таким чином, щоб кількість потоків легко змінювалася. Ваш підхід чудово узагальнює сили 2, але не так добре, як інші числа потоків.
Теодор Норвелл

2
@MaciejPiechotka Мораль - це майже все те, що ви пропонуєте. Але повертаючись до ОП, я вважаю, що найбільш релевантним є те, що багатопотокові програми дійсно можуть працювати (набагато) повільніше на багатоядерній архітектурі, ніж на одноядерному процесорі, якщо не буде витрачено зусиль для забезпечення іншого.
Теодор Норвелл
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.