Відповіді:
Основна відмінність між потоковим перемикачем та перемикачем процесу полягає в тому, що під час потокового комутатора простір віртуальної пам'яті залишається однаковим, тоді як він не відбувається під час перемикання процесу. Обидва типи передбачають передачу ядра операційної системи для виконання контекстного перемикання. Процес включення та виходу ядра ОС разом із витратами на вимикання регістрів є найбільшою фіксованою витратою на виконання контекстного комутатора.
Більш нечітка вартість полягає в тому, що контекстний комутатор змішується з механізмами кешування процесорів. В основному, коли ви перемикаєтесь на контекст, усі адреси пам'яті, які процесор "запам'ятовує" у своєму кеше, фактично стають марними. Основна відмінність тут полягає в тому, що при зміні просторів віртуальної пам’яті перемикаючий буфер перегляду процесора (TLB) процесора або його еквівалент вимивається, що робить доступ до пам'яті на деякий час дорожчим. Це не відбувається під час перемикання потоку.
Переключення контексту процесу включає перемикання адресного простору пам'яті. Сюди входять адреси пам'яті, відображення, таблиці сторінок та ресурси ядра - порівняно дорога операція. У деяких архітектурах це навіть означає перемикання різних кеш-процесорів, які не можна поділити в адресних просторах. Наприклад, x86 має промити TLB, а деякі ARM-процесори повинні повністю очистити кеш-пам'ять L1!
Переключення потоків - це перемикання контексту з однієї нитки на іншу в тому самому процесі (перехід від потоку до потоку через процеси - це просто переключення процесу).
Перш за все, операційна система переносить вихідний потік у режим ядра, якщо його вже немає, тому що комутація потоку може виконуватися лише між потоками, що працює в режимі ядра. Потім планувальник викликається, щоб прийняти рішення про тему, на яку буде виконуватися комутація. Після прийняття рішення ядро зберігає частину контексту потоку, яка знаходиться в ЦП (регістри процесора), на виділене місце в пам'яті (часто вгорі стека ядра вихідного потоку). Потім ядро виконує перехід від стека ядра вихідної нитки на стек ядра вхідного потоку. Після цього ядро завантажує раніше збережений контекст вхідного потоку з пам'яті в регістри процесора. І нарешті повертає управління назад у користувальницький режим, але у користувальницький режим нової нитки. У випадку, коли ОС визначила, що вхідний потік працюєВ іншому процесі ядро виконує ще один додатковий крок: встановлює новий активний віртуальний адресний простір.
Основна вартість в обох сценаріях пов'язана із забрудненням кешу. У більшості випадків робочий набір, використовуваний вихідною ниткою, істотно відрізнятиметься від робочого набору, який використовується вхідною ниткою. Як результат, вхідний потінок розпочне своє життя з лавини пропусків кешу, таким чином очищаючи старі та непотрібні дані з кешів та завантажуючи нові дані з пам'яті. Те ж саме стосується TLB (Buffer Translation Look Aside Buffer, який знаходиться на процесорі). У разі скидання віртуального адресного простору (потоки запускаються в різних процесах) штраф ще гірший, тому що скидання віртуального адресного простору призводить до вимивання всього TLB, навітьякщо новий потік насправді потребує завантаження лише декількох нових записів. Як результат, новий потік розпочне свій квантовий час із безліччю пропусків TLB та частою ходьбою по сторінках. Пряма вартість комутатора потоків також не є незначною (від ~ 250 і до ~ 1500-2000 циклів) і залежить від складності процесора, стану обох потоків і наборів регістрів, якими вони фактично користуються.
PS: Хороший пост про накладні перемикачі контексту: http://blog.tsunanet.net/2010/11/how-long-does-it-take-to-make-context.html
У режимі переключення контексту потоку простір віртуальної пам’яті залишається тим самим, поки це не стосується перемикання контексту контексту. Крім того, процесорний контекстний комутатор коштує дорожче, ніж перемикач контексту.
Я думаю, що головна відмінність полягає у виклику, switch_mm()
який обробляє дескриптори пам'яті старого та нового завдання. Що стосується потоків, то адресний простір віртуальної пам’яті є незмінним (потоки поділяють віртуальну пам’ять), тому потрібно зробити дуже мало, а отже, і менш витратно.
Хоча комутація контексту потоку повинна змінювати контекст виконання (регістри, покажчики стеків, лічильники програм), їм не потрібно змінювати адресний простір, як це роблять контекстні комутатори процесів. При переключенні адресного простору додаткові витрати, більший доступ до пам’яті (підказка, сегментація тощо), і вам доведеться стирати TLB під час входу чи виходу з нового процесу ...
Коротше кажучи, контекстний комутатор потоку не присвоює абсолютно новий набір пам'яті та pid, він використовує те саме, що і батьківський, оскільки він працює в рамках одного і того ж процесу. Процес породжує новий процес і, таким чином, призначає нові mem і pid.
До нього є ще лубуо. Вони написали про це книги.
Що стосується вартості, то вимкніть контекстний перемикач >>>>, оскільки вам доведеться скинути всі лічильники стеків тощо.
Якщо припустити, що CPU, на якому працює ОС, має декілька пристроїв із високою затримкою,
Має сенс запустити ще один потік адресного простору процесу, тоді як пристрій з високою затримкою відповідає на зворотній зв'язок.
Але, якщо пристрій з високою затримкою реагує швидше, ніж потрібно час, щоб створити таблицю + переклад віртуальної в фізичну пам’ять для НОВОГО процесу, тоді сумнівно, чи комутатор взагалі необхідний.
Крім того, кращий вибір кешу HOT (дані, необхідні для запуску процесу / потоку, доступні за менший час).