Домівка > C# > Різниця між асинхронністю і паралелізмом

Різниця між асинхронністю і паралелізмом

Якщо ви програмуєте на C#, то вам знайомі TPL і async/await, які стали чудовим надбанням для C# і фреймворка, а також вони породили багато запитань. Головне з яких:
В чім різниця між асинхронністю і паралелізмом?

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

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

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

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

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

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

Якщо async не запускує новий потік на тлі як він може виконати I/O зв’язані операції і не заблокувати при цьому UI потік?
Згадаймо, що фундаментально, I/O операції виконує залізо: існують якісь контролери дисків або мережи, вони обертають металевий диск або змінюють вольтаж на дроті, і ці штуки працюють незалежно від центрального процесора. ОС забезпечує абстракцію над апаратним рівнем, таку як I/O порти завершення. Конкретні подробиці про те скільки потоеів слухають I/O порт завершення і, що вони роблять по отриманні повідомлення, це складна система. Достатньо сказати, що вам не потрібен один потік на кожну асинхронну I/O oперацію.

Чи є async корисним лише для I/O зв’язаних операцій?
Це корисно щоразу коли результат обчислень значно віддалений у часі ві дмоменту коли цей результат потрібен. I/O операції є чудовим прикладом операції з високою затримкою, але це далеко не єдиний приклад. Уявімо, що вам потрібно виконати процесорно інтенсивні обчислення, які потребують декілька мільярдів машинних циклів. На багатопроцесорній машині немає сенсу для ЦП який виконує UI потік блокуватись допоки Цп, що виконує обчислення ще не завершив; UI потік повинен продовжувати обслуговувати UI. Або припустимо ви пишете гру. Коли гравець натискає кнопку програється сирена, затримка в три секунди, відкчиняються двері. Під час цих трьох секунд ви все ще хотіли б, щоб UI реагував на події. Затримка і наступне відкриття дверей логічні асинхронні операції; ви хочете, щоб потік працював поки він очікує на відчинення дверей, але це було б дійсно дивним стартувати новий потік для сирени, ще один для затримки і ще один для дверей.

Виходить, що можливість ОС доступна раніше лише для низькорівненвого програмування зараз доступна з мов високого рівня?
Асинхронний I/O завжди був доступним для C# програмістів; класи успадковані від Stream мають ReadAsync і BeginRead методи для асинхронного I/O. Однак, використання цих методів часто означає написання коду складним манером. Task Parallel бібліотека і await у C# 5 роблять набагато легшим написання коду який виглядає як традиційний синхронний, але є асинхронним.

Advertisements
Категорії:C# Позначки:
  1. Коментарів ще немає.
  1. No trackbacks yet.

Залишити відповідь

Заповніть поля нижче або авторизуйтесь клікнувши по іконці

Лого WordPress.com

Ви коментуєте, використовуючи свій обліковий запис WordPress.com. Log Out / Змінити )

Twitter picture

Ви коментуєте, використовуючи свій обліковий запис Twitter. Log Out / Змінити )

Facebook photo

Ви коментуєте, використовуючи свій обліковий запис Facebook. Log Out / Змінити )

Google+ photo

Ви коментуєте, використовуючи свій обліковий запис Google+. Log Out / Змінити )

З’єднання з %s

%d блогерам подобається це: