Скільки зусиль потрібно витратити на програмування для декількох ядер?


12

У цей час процесори отримують все більше ядер, що мене цікавить ...

Чи повинні ми, програмісти, адаптуватися до такої поведінки і витратити більше зусиль на програмування для декількох ядер?

Якою мірою ми повинні це зробити та оптимізувати? Нитка? Спорідненість? Оптимізація обладнання? Щось ще?

Відповіді:


15

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

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

Вам потрібно знати про те, як керуються цими потоками, щоб ви могли найкраще використовувати ресурси. Не створювати занадто багато ниток - це одне, що спадає на думку як приклад.

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


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

@Lorenzo - У такому випадку вам потрібно буде перевірити, чи зможете ви прив’язати нитку до єдиного ядра - що, мабуть, є окремим випадком - але цікавим.
ChrisF

1
Хіба це не буде досить дивним кроком для того, щоб ОС переключала активний потік з одного ядра на інший?
JBRWilkinson

Я погоджуюся з @JBRWilkinson, спорідненість ниток здається мені роботою з ОС.
Колін

1
@JBRWilkinson Під linux (і я думаю, що більшість ОС) потоки постійно перескакують між ядрами. Перша причина полягає в тому, що у вас набагато більше ниток, ніж ядер. І якщо деякі нитки вмирають, то вам потрібно врівноважити. Друга причина - багато сплячих ниток. І коли деякі прокидаються, ядро ​​може подумати, що одне ядро ​​має більше навантаження, ніж інші, і переміщає потік, часто ваш процесор вивішує обчислювальну нитку. Потім на одному ядрі працюють два нитки процесорного процесора, поки ядро ​​не переміститься назад. Якщо ви розділяєте велику роботу на точно деталі з числом ядер, тоді ви хочете встановити спорідненість потоку.
Госвін фон Бредерлоу

5

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

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

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


5

У країні Objective-C та Mac OS X та iOS рамки (як і багато інших) написані, щоб скористатися цим збільшенням процесорних ядер та подарувати розробнику приємний інтерфейс для їх використання.

Приклад для Mac OS X та iOS - це відправлення Grand Central. Існують доповнення до libc(я вважаю) для полегшення багаторядкової нарізки на основі черги. Потім рамки какао та фундаменту (серед інших) записуються поверх GCD, що дає розробнику простий доступ до черг відправки та нарізки з дуже невеликим кодом плит котла.

Багато мов та рамок мають подібні поняття.


5

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

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


3

Ми зараз (жовтень 2010 р.) В час величезного переходу.

Сьогодні ми могли б придбати 12-ядерний робочий стіл.
Сьогодні ми могли б придбати основну карту обробки 448 (пошук NVidia Tesla).

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

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

Надалі нам потрібно буде розділити нашу обробку на дискретні шматки для незалежної обробки, використовуючи абстракції на зразок нової .NET "Рамки завдань".

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


3

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

у більшості випадків ґрунтовне розуміння та використання замків, ниток та завдань та пулів завдань стане хорошим початком, коли необхідна паралелізм. (залежить від lang / lib)

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

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

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

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

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

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

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


2

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

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


0

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

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

Для багатопотокового програмування ви побачите, що ви отримаєте зменшення віддачі від своєї продуктивності; ви можете витратити години та покращити програму на 15%, а потім витратити ще тиждень і лише покращити її ще на 5%.

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