Щоб припустити підвищення швидкості за рахунок будь-якої форми багатокомп'ютерних обчислень, ви повинні припустити, що кілька задач на основі процесора виконуються одночасно на кількох обчислювальних ресурсах (як правило, ядра процесора), або ж, що не всі завдання покладаються на одночасне використання той самий ресурс - тобто деякі завдання можуть залежати від одного системного підкомпонента (дискове зберігання, скажімо), тоді як деякі завдання залежать від іншого (отримання зв'язку з периферійного пристрою), а інші можуть вимагати використання процесорних ядер.
Перший сценарій часто називають "паралельним" програмуванням. Другий сценарій часто називають "одночасним" або "асинхронним" програмуванням, хоча "паралельний" іноді також використовується для позначення випадку просто дозволу операційній системі переплутати виконання декількох завдань, незалежно від того, чи потрібно таке виконання розміщуйте серійно або якщо для досягнення паралельного виконання можуть використовуватися кілька ресурсів. В цьому останньому випадку "паралельний", як правило, відноситься до того, що виконання записується в програмі, а не з точки зору фактичної одночасності виконання завдання.
Про все це дуже просто говорити з негласними припущеннями. Наприклад, деякі швидко висувають претензію на зразок "Асинхронний введення / виведення буде швидше, ніж багатопотоковий введення / виведення". Ця претензія сумнівна з кількох причин. По-перше, може статися так, що деякі задані асинхронні рамки вводу / виводу реалізуються саме з багатопотоковою резьбою, і в цьому випадку вони однакові, і немає сенсу говорити, що одна концепція "швидше, ніж" інша .
По-друге, навіть у випадку, коли є однопоточна реалізація асинхронного фреймворку (наприклад, однонитковий цикл подій), ви все одно повинні зробити припущення про те, що робить цей цикл. Наприклад, одна нерозумна річ, яку ви можете зробити з однопоточним циклом подій, - це запит, щоб вона асинхронно виконала дві різні, суто пов'язані з процесором завдання. Якщо ви зробили це на машині з лише ідеалізованим ядром одного процесора (ігноруючи сучасні аппаратні оптимізації), то виконання цього завдання "асинхронно" насправді не було б інакше, ніж виконувати його з двома незалежно керованими потоками, або лише з одним самотнім процесом - - різниця може звестись до переключення контексту потоку або оптимізації розкладу операційної системи, але якщо обидва завдання надходять до центрального процесора, це було б у будь-якому випадку схожим.
Корисно уявити безліч незвичайних або дурних кутових справ, в які ви можете зіткнутися.
"Асинхронний" не повинен бути паралельним, наприклад, так само, як вище: ви "асинхронно" виконуєте два завдання, пов'язані з процесором, на машині з точно одним процесорним ядром.
Багатопотокове виконання не повинно бути одночасним: ви породжуєте два потоки на машині з одним ядром процесора або просите два потоки придбати будь-який інший дефіцитний ресурс (уявімо, скажімо, мережеву базу даних, яка може встановити лише один з'єднання за раз). Виконання потоків може бути переплетено, проте планувальник операційної системи вважає за потрібне, але їх загальний час виконання не може бути зменшений (і буде збільшено за допомогою перемикання контексту потоку) на одному ядрі (або в більш загальному випадку, якщо ви породжуєте більше потоків, ніж є ядра для їх запуску або мають більше потоків із запитом про ресурс, ніж те, що ресурс може підтримувати). Це ж стосується і багатопроцесорної обробки.
Таким чином, ні асинхронний введення / виведення, ні багатопотокова передача не повинні пропонувати будь-яке підвищення продуктивності з точки зору часу виконання. Вони навіть можуть уповільнити справи.
Якщо ви визначите конкретний випадок використання, як-от конкретна програма, яка одночасно здійснює мережевий виклик для отримання даних із підключеного до мережі ресурсу, наприклад віддаленої бази даних, а також виконує деякі локальні обчислення, пов'язані з процесором, тоді ви можете почати міркувати про відмінності в продуктивності між двома методами дають певне припущення про обладнання.
Запитання, які слід задати: Скільки обчислювальних кроків мені потрібно виконати і скільки незалежних систем ресурсів існує для їх виконання? Чи є підмножини обчислювальних кроків, які вимагають використання незалежних підкомпонентів системи і можуть отримати користь від цього одночасно? Скільки ядер процесора у мене є і яка накладні витрати на використання декількох процесорів або потоків для виконання завдань на окремих ядрах?
Якщо ваші завдання багато в чому залежать від незалежних підсистем, то асинхронне рішення може бути корисним. Якщо кількість потоків, необхідних для його оброблення, буде великою, такою, щоб контекстна комутація стала нетривіальною для операційної системи, то однопотокове асинхронне рішення може бути кращим.
Кожного разу, коли завдання пов'язані одним і тим же ресурсом (наприклад, кілька потреб для одночасного доступу до однієї мережі або локального ресурсу), то багатопотокова передача, ймовірно, введе незадовільні накладні витрати, і в той час як однопотокова асинхронія може вводити менше накладних витрат, обмежена ситуація теж не може призвести до прискорення. У такому випадку єдиний варіант (якщо ви хочете прискорити роботу) - це зробити доступними кілька копій цього ресурсу (наприклад, декілька ядер процесора, якщо дефіцитним ресурсом є процесор; краща база даних, яка підтримує більше одночасних з'єднань, якщо дефіцитний ресурс це база даних з обмеженим з'єднанням тощо).
Інший спосіб зробити це: дозволити операційній системі переплутати використання одного ресурсу для двох завдань не може бути швидше, ніж просто дозволити одній задачі використовувати ресурс, а інша чекати, а потім дозволити другій задачі послідовно закінчуватися. Крім того, вартість планувальника переплетення означає в будь-якій реальній ситуації, що насправді створює уповільнення. Не має значення, чи відбувається перемежоване використання процесора, мережевого ресурсу, ресурсу пам'яті, периферійного пристрою чи будь-якого іншого системного ресурсу.