Quando você divide um algoritmo/função/qualquer coisa para executar como threads separadas, digamos que eu lanço 8 threads, você não sabe que cada thread será executada em um dos meus 8 núcleos, pois é tarefa do planejador decidir quais threads serão dadas a quais núcleos. Ainda assim, se eu tiver 8 núcleos e dividir um trabalho em 8 threads, eu praticamente espero que isso aconteça, cada um dos meus 8 núcleos (aproximadamente) levará um oitavo da carga de trabalho. No caso de processadores Intel que têm núcleos P e E (núcleos de desempenho e eficiência), os núcleos P podem ter clock de 5,4 GHz e os núcleos E podem ter clock de 4,2 GHz. Esse tipo de processador com dois tipos diferentes de processadores torna a programação multithread mais imprevisível ou menos desejável? O sistema de duas camadas é comum em outros dispositivos, como smartphones e CPUs da Apple, e a mesma pergunta se aplica. Como programador, como você deve levar em conta o fato de que quando você executa algo em um thread diferente, digamos que você gera um novo thread ou outro thread está esperando em um pool de threads por um trabalho, ele pode ser executado em um núcleo de desempenho ou em um núcleo de eficiência? Você tem alguma escolha?
relate perguntas
-
Propriedades JMeter gravando simultaneamente
-
Como usar uma variável de estado Tauri gerenciada dentro de um thread de tempo de execução assíncrono Tauri gerado?
-
Um println extra no thread principal faz com que o Rust execute resultados diferentes
-
ideal para liberar atômicos de baixa contenção dos caches?
-
Rust: Itere em uma pasta e abra cada arquivo
Se você dividir sua carga de trabalho em partes de tamanhos iguais, os P-cores terminarão primeiro. Mas se você dividir em partes menores e fizer com que os threads peguem outro pedaço quando terminarem o primeiro, como OpenMP schedule=dynamic em vez de static, você pode manter todos os núcleos ocupados até que todo o trabalho esteja concluído.
Ou se houver muitas tarefas paralelizáveis a serem feitas, e as posteriores puderem começar enquanto alguns threads da primeira ainda estiverem sendo finalizados, isso facilita o envio de trabalho para um pool de threads.
Dividir seu trabalho em 8 partes de tamanhos iguais para uma CPU de 8 núcleos pode ser ruim mesmo em uma CPU homogênea se houver qualquer outra carga: se alguns threads forem desprogramados por um tempo, eles não terminarão tão cedo quanto os threads que foram executados o tempo todo. (Especialmente se o tempo total estiver na mesma escala de um grânulo de agendamento, por exemplo, 10 ms para Linux com HZ=100.)
Então já há motivos para dividir o trabalho em pedaços de tamanho moderado para os threads consumirem, especialmente se você estiver usando um sistema de pool de threads sofisticado como o OpenMP, que pode fazer isso por você sem precisar escrever muito código extra.