Como os núcleos da CPU são distribuídos para cada kernel no cálculo de paralelização?
Só quero ter certeza de que entendi corretamente antes de fazer perguntas. Eu vi algumas pessoas dizendo que algumas funções no Mathematica vão usar multi-núcleos automaticamente (não estou me referindo àquelas que paralelizamos, mas me referindo a outras como NIntegrate
), então acho que se eu tiver 2 núcleos, será mais rápido que único testemunho. Então, minhas dúvidas são se eu tenho um código como o seguinte:ParallelTable[NIntegrate[x, {x, 1, 3}], {loop, 1, 3}]
Acho que três kernels serão lançados. Se eu tiver 4 núcleos, como esses quatro núcleos são distribuídos para cada kernel? (Já que acho que cada kernel pode usar multi-núcleos com base na propriedade de integração de funções)
Respostas
Bem-vindo noo-b, m.se é uma grande comunidade para aprendizado infinito sobre M!
Acho que você tem algumas suposições falsas:
Em primeiro lugar, mesmo as operações de thread único podem encadear em vários núcleos. Um bom sistema operacional tenta evitar isso, mas a cada tantos segundos, ele pode mudar para outro núcleo, ou pode dividir a carga em vários núcleos - embora o último geralmente não por um longo tempo.
Em segundo lugar, você não pode supor que o NIntegrate sempre paralelizará para todas as entradas e, em particular, você não pode supor que o NIntegrate paralelizará durante todo o tempo de computação. Ele pode paralelizar apenas para a inicialização ou no final, ou em tarefas selecionadas no meio. Por exemplo,
Do[Do[NIntegrate[x,{x,1,3}],{3}],{100000}]
se você olhar para a utilização do núcleo (não: utilização do processo, como em um gerenciador de tarefas simples) - se você estiver no Linux, você pode executar top e bater 1 - você verá que isso gasta 99% do tempo em um núcleo. Pode mudar o núcleo depois de algum tempo, mas então você vê 99% para esse núcleo. Portanto, não vejo o NIntegrate threading em vários núcleos, pelo menos não o tempo todo (talvez por frações de segundos). Isso pode ser diferente para diferentes entradas NIntegrate, mas este exemplo simples mostra que NIntegrate nem sempre paraleliza e não durante toda a sua computação.
Com a estrutura de paralelismo M, isso não muda, é realmente uma questão de sistema operacional. Com ParallelTable (e irmãos), você está apenas fornecendo tarefas de processamento de mais processos, e como o o / s agenda isso para os núcleos é inteiramente por conta do o / s. Portanto, você não pode realmente "desistir" da atribuição aos núcleos de uma compreensão dos processos paralelos.
algo como uma tangente:
Em Scala, Java ou C # (ou muitas outras linguagens), você pode agendar tarefas em um nível de thread. Mas, mesmo assim, cabe ao o / s programar os passos para os núcleos. Com o vmstat do Java você tem uma visualização maravilhosa dos threads (barras horizontais que crescem com o tempo, uma por thread), acho que você está realmente interessado em como as coisas funcionam nos threads, não necessariamente como os threads são atribuídos aos núcleos . Com isso dito, porém, os threads são um conceito de software, não um conceito de hardware, um núcleo não sabe o que é um thread. Mas acho que uma análise de encadeamento diria mais para entender a simultaneidade, já que a atribuição aos núcleos e a comutação de núcleos e as porcentagens de carga de trabalho para cada núcleo depende inteiramente do o / s.
Existem algumas funções que usam vários núcleos automaticamente. Quantos núcleos eles usam é determinado por algumas das configurações em SystemOptions["ParallelOptions"]
.
Se você usar essas funções em subkernels, eles usarão apenas um único núcleo. Você pode verificar isso olhando para ParallelEvaluate@SystemOptions["ParallelOptions"]
. Observe que todas as contagens de encadeamentos são definidas como 1 nos subkernels.
Geralmente, a paralelização explícita (como ParallelTable
) não é tão eficiente quanto a paralelização interna de algumas funções. Portanto, se o seu gargalo é uma função que já executa em paralelo, a implementação de paralelização adicional com ParallelTable
ou funções relacionadas irá torná-lo mais lento (ou pelo menos diminuiu em todos os casos que verifiquei).