Quando você inicia vários threads em um processador com vários núcleos, eles garantem que sejam processados ​​por diferentes núcleos?


24

Eu tenho um processador Pentium Core i5, que possui 4 núcleos. Se eu fizer isso em um programa de console C #

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

os threads t1 e t2 têm garantia de execução em núcleos separados?


1
Supondo que o tempo de execução C # use chamadas nativas equivalentes do sistema para gerar outro encadeamento (e, portanto, é verdadeiramente paralelo; esse não é o caso de tudo, como o infame Global Interpreter Lock do CPython ), isso dependeria apenas do processo / agendador de tarefas do sistema operacional . Em geral, porém, o código é verdadeiramente seguro para threads se você assumir isso t1e t2for executado em momentos diferentes em uma ordem arbitrária (por exemplo, é possível t2iniciar antes t1 em alguns modelos).
Breakthrough

2
Eu não sabia que havia processadores Pentium i5. Talvez você quis dizer Core i5? Exigente. Eu sei: D
JosephGarrone

Respostas:


18

Você não pode garantir no .net que dois Threads sejam executados em dois núcleos separados. De fato, você também não pode garantir que um Threadseja executado em apenas um núcleo (!) .

Isso ocorre porque os threads gerenciados não são iguais aos threads do SO - um único Thread gerenciado pode usar vários threads do SO para suportá-lo. Em C #, você só lida diretamente diretamente com Threads gerenciados (pelo menos, sem recorrer a p / invoke para chamar as funções de threading do WinAPI, o que você nunca deve fazer) .

No entanto, os agendadores de threads .Net e Windows são muito bons no que fazem - eles não executariam dois threads em um único núcleo enquanto um segundo núcleo fica completamente inativo. Portanto, em geral, você não precisa se preocupar com isso.


Na prática, .Net Threads são threads de SO. Mas não é por isso que não há garantia de que um único encadeamento sempre seja executado no mesmo núcleo.
precisa

2
@svick: Na prática, no x86 , isso é verdade. No entanto, o padrão declara explicitamente que você não pode confiar nesse comportamento; portanto, ele pode mudar no futuro. De fato, isso não é verdade em outras versões do .Net CLR, como o XBox 360.
BlueRaja - Danny Pflughoeft

@BlueRaja - A pergunta é específica sobre qual versão do CLR estamos falando. Você pode garantir que algo existirá em dois núcleos separados usando threads assíncronos, pois isso significaria que eles aconteceriam de maneira assíncrona. O código de exemplo atual é uma chamada de sincronização tecnicamente. Obviamente, o sistema operacional decide quais núcleos seriam usados.
Ramhound

@ Ramhound "Você pode garantir a existência de algo em dois núcleos separados usando threads assíncronos" - isso é falso. A asyncpalavra-chave (que é do que suponho que você esteja falando, como "threads assíncronos" é redundante) é apenas um açúcar sintático para usar um BackgroundWorkerthread, que é como qualquer outro thread .Net - você não pode garantir se será executado em um núcleo separado ou não.
BlueRaja # Danny Pflughoeft

@BlueRaja - Se dois threads assíncronos fossem iniciados, ambos rodariam ao mesmo tempo, desde que houvesse 2 núcleos de CPU. Se houvesse apenas um, o sistema operacional agendaria quando cada encadeamento teria prioridade e execução e sua situação típica de debulhamento de encadeamento único ocorreria. Foi assim que me ensinaram como uma CPU lida com vários threads.
Ramhound

15

Não, o sistema operacional e a CPU decidirão o que executar e quando. no exemplo simples que você mostrou, com exclusão de outras tarefas, sim, essas provavelmente seriam executadas em paralelo em núcleos separados, mas raramente há garantia de que esse será o caso.

Você pode usar a afinidade do encadeamento para tentar assumir algum controle sobre a alocação de um núcleo para um determinado encadeamento.

Considere também planejar prioridades para empilhar o deck em termos de quais threads devem ser totalmente paralelos e quais podem esperar.


1
Também quero acrescentar que, com as tecnologias de virtualização, existe outra camada entre o seu programa e o hardware. O que o sistema operacional apresenta ao aplicativo pode não ser fisicamente preciso.
precisa saber é o seguinte

1
Essas são funções WinAPI para threads do SO, não para threads gerenciadas. Eles nunca devem ser chamados de C #, pois podem interferir seriamente com o agendador de threads .Net.
BlueRaja - Danny Pflughoeft
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.