Коли ви запускаєте кілька потоків на багатоядерному процесорі, чи гарантовано вони обробляються різними ядрами?


24

У мене є процесор Pentium core i5, який має 4 ядра. Якщо я це роблю в консольній програмі C #

var t1 = new Thread(Thread1);
var t2 = new Thread(Thread2);
t1.Start();
t2.Start();

чи гарантовано потоки t1 і t2 на окремих ядрах?


1
Якщо припустити, що час виконання C # використовує еквівалентні нативні системні виклики, щоб породити інший потік (і, таким чином, справді паралельний; це не стосується всього, як, наприклад, сумнозвісного глобального блоку інтерпретатора CPython ), це залежатиме виключно від планувальника процесу / завдання оператора . Взагалі , хоча, код дійсно поточити якщо припустити , що t1і t2виконуються в різний час в довільному порядку (наприклад , це можливо t2починається до t1 того, в деяких моделях).
Прорив

2
Я не знав, що є процесори Pentium i5. Можливо, ви мали на увазі Core i5? Вибагливий. Я знаю: D
ДжозефГарроне

Відповіді:


18

Ви не можете гарантувати в. Немає того, що два Threads працюють на двох окремих ядрах. Насправді ви також не можете гарантувати, що один Threadзапуск буде працювати лише на одному ядрі (!) .

Це відбувається тому, що керовані потоки не збігаються з потоками ОС - одна керована Нитка може використовувати декілька потоків ОС для її підтримки. У C # ви завжди працюєте безпосередньо з керованими Threads (принаймні, не вдаючись до p / invoke для виклику функцій нарізки WinAPI, чого ви ніколи не повинні робити) .

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


На практиці .Net Threads - це потоки ОС. Але це не є причиною того, що немає жодної гарантії того, що один потік завжди буде виконуватися на одному ядрі.
svick

2
@svick: На практиці на x86 це правда. Однак стандарт прямо зазначає, що не можна покладатися на таку поведінку, тому це може змінитися в майбутньому. Насправді, це НЕ правда , на інших версіях .NET CLR, як XBox 360.
BlueRaja - Danny Pflughoeft

@BlueRaja - Питання є конкретним щодо того, про яку версію CLR ми говоримо. Ви можете гарантувати, що щось буде існувати на двох окремих ядрах, використовуючи нитки асинхронізації, оскільки це означатиме, що вони відбудуться асинхронізацією один з одного. Поточний код прикладу - це технічний виклик синхронізації. Звичайно, операційна система вирішує, які ядра будуть використовуватися.
Рамхаунд

@Ramhound "Ви можете гарантувати, що на двох відокремлених ядрах щось буде, використовуючи нитки асинхронізації" - це неправда. asyncКлючове слово (що я припускаю , що ви говорите, як «асинхронними потоками» є зайвим) просто синтаксичний цукор для використання BackgroundWorkerнитки, яка , як і будь-який інший .Net темі - ви можете не гарантія того , що буде працювати на окреме ядро ​​чи ні.
BlueRaja - Danny Pflughoeft

@BlueRaja - Якщо запускалися два потоки асинхронізації, вони обидва запускалися б одночасно за умови наявності 2 ядер CPU. Якби був лише один, операційна система запланувала б, коли кожен потік отримає пріоритет і запуститься, і трапиться ваша типова ситуація, що обмотається з одною ниткою. Так мене вчили, як процесор обробляє багатопотокові.
Рамхаунд

15

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

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

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


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

1
Це функції WinAPI для потоків ОС, а не для керованих потоків. Їх ніколи не слід викликати з C #, оскільки вони можуть сильно заважати планувальнику потоків .Net.
BlueRaja - Danny Pflughoeft
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.