Щоб виправити метафору EightBitTony:
"Чому це відбувається?" легко відповісти. Уявіть, у вас є два басейни, один повний і один порожній. Ви хочете перенести всю воду з одного на інший і мати 4 відра . Найбільш ефективна кількість людей - 4.
Якщо у вас є 1-3 людини, то ви не вистачаєте на використання відра . Якщо у вас є 5 і більше людей, то принаймні один з цих людей застрягає, чекаючи відра . Додавання все більшої кількості людей ... не прискорює діяльність.
Тож ви хочете мати стільки людей, скільки може одночасно виконати певну роботу (використовувати відро) .
Людина тут - це нитка, і відро являє собою який би ресурс виконання був вузьким місцем. Додавання більше тем не допоможе, якщо вони нічого не можуть зробити. Крім того, ми повинні підкреслити, що передача відра від однієї людини до іншої, як правило, повільніше, ніж одна людина, яка просто переносить відро на однаковій відстані. Тобто, два потоки, що обертаються на сердечнику, зазвичай виконують менше роботи, ніж одна нитка, яка працює вдвічі довше: це через додаткову роботу, виконану для перемикання між двома потоками.
Незалежно від того, чи обмежуючий ресурс виконання (bucket) - це процесор, або серцевина, або гіперпотоковий конвеєр інструкцій для ваших цілей, залежить від того, яка частина архітектури є вашим обмежуючим фактором. Зверніть увагу також, що ми припускаємо, що потоки повністю незалежні. Це лише в тому випадку, якщо вони не поділяють даних (і уникають будь-яких зіткнень кешу).
Як підказали кілька людей, для вводу / виводу обмежуючим ресурсом може бути кількість корисно введених операцій вводу / виводу: це може залежати від цілого ряду апаратних та ядерних факторів, але може бути набагато більшим, ніж кількість сердечники. Тут контекстний комутатор, який настільки дорогий порівняно з кодом, який пов'язаний з виконанням, є досить дешевим порівняно з кодом, пов'язаним з введенням / виводу. На жаль, я думаю, що метафора повністю вийде з-під контролю, якщо я спробую виправдати це відрами.
Зауважте, що оптимальне поведінка з пов'язаним кодом вводу / виводу, як правило, все ще має мати щонайменше один потік на трубопровід / ядро / процесор. Однак вам потрібно записати асинхронний або синхронний / не блокуючий код вводу / виводу, і порівняно невелике поліпшення продуктивності не завжди виправдає зайву складність.
PS. Моя проблема з оригінальною метафорою коридору - це настійно говорить про те, що ви маєте змогу мати 4 черги людей, 2 черги, що перевозять сміття, і 2, які повертаються, щоб зібрати більше. Після цього ви можете зробити кожну чергу майже до тих пір , як коридор, і додають люди зробили швидкість до алгоритму (ви в основному перетворили весь коридор в конвеєрній стрічці).
Насправді цей сценарій дуже схожий на стандартний опис взаємозв'язку між затримкою та розміром вікна в мережі TCP, тому він вискочив у мене.