Eu queria saber se existe uma maneira simples de "ativar" todos os 100% da CPU para que eu possa executar processos mais rapidamente (como cálculos em python).
1) Isso é possível?
2) Existe uma maneira fácil de voltar ao normal?
3) Existe uma maneira de usar menos CPU, se desejado?
Estou pensando em uma interação de linha de comando como:
pi@raspberry:~ $ sudo turnOnFourCores python run.py
Respostas:
Por padrão, qualquer computador tentará usar todos os seus núcleos quando puder. No entanto, isso só é possível quando um aplicativo é multiencadeado. Se não for (ou seja, um script Python que não use o
threading
módulo), ele poderá usar no máximo apenas um núcleo. Isso equivale a 25% da CPU em uma CPU de quatro núcleos. Se você deseja modificar seu script para usar vários núcleos, divida seu cálculo em várias partes e faça várias threads, como mostra a documentação do Python .Atualizar:
Como Anon respondeu , isso não funcionará sem o trabalho com o GIL (Global Interpreter Lock) do Python. Isso permite que as tarefas operem (aparentemente) ao mesmo tempo, mas não permite que o código seja executado em vários núcleos. Se você estiver usando módulos escritos em C (por exemplo, numpy), eles poderão permitir o uso de vários núcleos, contornando essa limitação. Além disso, se essa não for uma opção, o Python oferece multiprocessamento , o que permite executar qualquer tarefa em vários núcleos.
fonte
Não no sentido em que acho que você está implicando. Esse também não é um problema específico do pi, é uma restrição lógica.
Por si só, os computadores atualmente não têm muita capacidade para determinar que um processo em execução como um único encadeamento possa ser executado em paralelo. Observe que no momento em que eles podem ter essa capacidade, não há necessidade de programadores de computador, porque um sistema de computador que pode fazer isso também pode escrever seu próprio código 1 ..
Considere a seguinte expressão matemática simples:
Existe algum potencial para que isso seja calculado em paralelo, mas é logicamente limitado. Eu diria que não há sentido em mais de dois threads, e mesmo assim ele será apenas um:
O segmento 2 contribuiu calculando 3 + 6 = 9, usado na etapa C pelo segmento 1, salvando-o em uma etapa. Mas isso é o mais longe que o paralelismo chegará aqui. Embora o segmento 2 possa calcular 17/9 enquanto o número 1 faz 6 * 17, isso seria inútil, porque agora você tem dois caminhos diferentes para o mesmo objetivo que não podem ser recombinados. Ou seja, o número 2 poderia continuar trabalhando:
E acabam com o mesmo resultado que o segmento nº 1 (11.333), mas eles não se ajudaram além da etapa A, portanto, fazer com que dois deles perseguissem esse objetivo é uma perda de tempo.
(Observe que este exemplo não é literal; ele pretende demonstrar um princípio lógico. A escala na qual as tarefas são encadeadas no código do usuário é muito maior, mas você não precisa de uma lição real de programação multithread para poder compreenda a ideia aqui.)
A exploração de vários processadores requer código escrito para isso. Você não pode simplesmente pegar qualquer coisa e dizer: "use todos os 4 núcleos e faça-o mais rápido!". Não é isso que aconteceria. Logicamente, muitos (... ou a maioria) problemas e tarefas envolvem etapas que não podem ocorrer em paralelo; elas devem ocorrer em sequência.
1. Mas veja o comentário de Felix Dombek abaixo; Eu não sou um especialista em IA. Também pode ser interessante notar que, de acordo com os comentários de Peter Corde, os conjuntos de instruções e processadores contemporâneos podem ser explorados pelo sistema operacional para otimizar coisas muito refinadas de maneira paralela, e os pipelines de hardware fazem isso também, embora não entre núcleos (um único o core tem mais de uma coisa acontecendo, operando no fluxo de instruções em vários pontos antes da execução final). Eu estava tentando me ater ao tópico de threads de usuário aqui, pois acho que isso é mais ou menos o que você está entendendo.
fonte
add
instruções próximas uma da outra, para que ambas possam executar na mesma ciclo do relógio. O seguinte multiplicar e dividir resto será serializado por dependências de dados, como você aponta.Não para python.
Outras pessoas estão sugerindo que você procure por threading, que é uma resposta válida para a maioria dos idiomas, mas eles não levaram em conta que você está usando python.
O python GIL não permite que você efetivamente use vários núcleos.
fonte
O uso de vários núcleos requer a exposição explícita do paralelismo no nível do encadeamento ao sistema operacional, o que geralmente exige que o programador grave um programa com vários encadeamentos . (Ou para executar um programa de thread único várias vezes em entradas diferentes, como compilar com
make -j4
)Os compiladores para alguns idiomas oferecem suporte à paralelização automática. Por exemplo, C ou C ++ com OpenMP podem compilar um
for()
loop comum em um programa que inicia vários threads.Mas ainda assim, isso precisa acontecer quando você escreve ou compila o programa. Não há como o hardware e os sistemas operacionais atuais usarem vários núcleos para acelerar um programa de thread único.
Relacionado: Como um único encadeamento é executado em vários núcleos? : resposta: eles não. Mas existem outros tipos de paralelismo, como o paralelismo no nível da instrução que um único núcleo da CPU encontra e explora para executar um único encadeamento mais rapidamente do que uma instrução por vez.
Minha resposta a essa pergunta entra em alguns detalhes de como as CPUs modernas encontram e exploram um paralelismo detalhado no nível das instruções. (Principalmente o x86). Isso é apenas parte de como as CPUs normais funcionam, tendo várias instruções em andamento ao mesmo tempo, e não é algo que você precisa habilitar especialmente. (Existem contadores de desempenho que permitem ver quantas instruções por clock sua CPU conseguiu executar durante a execução de um programa ou outras medidas.)
Observe que o RPi3 usa núcleos de CPU ARM Cortex-A53 em ordem . Cada núcleo é superescalar de 2 largos (2 instruções por relógio, conforme o ILP permite), mas não pode reordenar as instruções para encontrar mais paralelismo no nível das instruções e ocultar a latência.
Ainda assim, a CPU é canalizada, portanto, o número total de instruções em andamento (desde a busca e decodificação até o estágio de write-back no final do pipeline) é significativo. Quando as dependências de dados não limitam as coisas, pode haver 2 instruções em cada estágio do pipeline em que a CPU está trabalhando, com uma taxa de transferência de 2 instruções por relógio. (Isso é o que significa 2).
Ele não pode executar instruções fora de ordem, mas com uma ordenação cuidadosa de instruções (geralmente por um compilador), ainda pode ocultar a latência de uma instrução que leva vários ciclos para que sua saída esteja pronta. (por exemplo, uma carga, mesmo que seja atingida no cache ou em uma multiplicação, levará vários ciclos, contra uma adição estar pronta no próximo ciclo). O truque é solicitar as instruções asm para que haja várias instruções independentes entre a que produz um resultado e a que o utiliza.
Ter o software (um compilador) agendando estaticamente as instruções é mais frágil do que o hardware que pode ser reordenado internamente, preservando a ilusão de execução na ordem do programa. É muito difícil para os compiladores fazerem um trabalho tão bom quanto uma pequena janela fora de ordem para reordenar as instruções, porque as falhas no cache são imprevisíveis e é difícil analisar as cadeias de dependência nas chamadas de função em tempo de compilação. E o número de registros é limitado sem a renomeação de registros de hardware.
Tudo isso é um pequeno conforto quando o código é mais lento do que você gostaria. Certamente, há um monte de coisas legais embaixo do capô em um Cortex-A53, mas há mais coisas legais embaixo do capô em um Cortex-A57 (como execução fora de ordem de até 3 instruções por relógio) e ainda mais uma grande CPU x86 como a Skylake (sem mencionar as diferenças de velocidade do relógio).
O Cortex-A53 é fantástico, comparado a um https://en.wikipedia.org/wiki/Classic_RISC_pipeline como MIPS original que você aprenderia na aula de arquitetura de computadores, mas, pelos padrões modernos, é bastante barato.
fonte
java
não émyapp.jar
, e certamente não é único.Não é assim que as CPUs funcionam ... de jeito nenhum.
Como está atualmente, sua CPU é perfeitamente capaz de funcionar com 100% de uso, assumindo que não está sendo acelerada devido a problemas relacionados à temperatura a 80 graus Celsius ou mais. Dito isto, você geralmente não deseja ver sua CPU fixada em 100%. Se você está rotineiramente com 100% de utilização da CPU, provavelmente tem muito para o seu processador suportar. Isso causará gagueira e uma experiência do usuário geralmente infeliz.
Para comparar com algo mais físico, a utilização da CPU é muito parecida com um carro. O carro provavelmente é capaz de percorrer 160 km / h, mas há uma boa chance de seu velocímetro ler algo significativamente abaixo disso. Quando estiver na cidade, você poderá nunca conseguir cerca de 40 km / h. Isso não muda no entanto que o carro pode ir a 100 mph. Você simplesmente não pressionou o acelerador com força suficiente.
Se você simplesmente fizer o RPi fazer mais coisas (pressione mais o acelerador), você verá o valor de utilização da CPU subir. Por exemplo, observe a utilização da CPU ao executar o comando
yes
em uma janela do terminal (lembre-se de quectrl+c
termina os comandos do terminal). Isso aumentará sua CPU em 25%, pois maximiza um de seus quatro núcleos de CPU.fonte
As outras respostas fornecem bons detalhes, mas não parecem abordar suas perguntas especificamente.
NB:
Se você deseja melhorar o desempenho geral do pi, convém examinar o Overclocking. Isso permite que a CPU seja executada em uma taxa mais rápida. As desvantagens são aumento da produção de calor, menor vida útil do processador e aumento do consumo de energia.
fonte
Se possível, eu parametrizaria o script e os executaria em processos Python separados. Por exemplo:
Uma outra alternativa é a biblioteca de multiprocessamento já mencionada, que permite a junção de processos python. Mas isso também exige que você tenha uma lista de parâmetros (como um nome de arquivo) para os quais deseja que os cálculos sejam executados.
fonte
map
mas aparentemente ele também possui muitas construções de memória compartilhada bastante sofisticadas.Eu acho que o OP pode não entender completamente os conceitos de programação multi-core / multi-thread e como é difícil utilizar totalmente 100% do multi-core, a menos que o algoritmo possa ser facilmente transformado em um problema embaraçosamente paralelo .
Para mais informações, você pode ler mais sobre o conhecido título do artigo "O almoço gratuito acabou" http://www.gotw.ca/publications/concurrency-ddj.htm
fonte
Se você deseja testar seu RPI. Você pode executar
stress
como aqui , e pode ver como suas CPUs estão sendo usadashtop
. Isso é útil porque você pode ver se sua fonte de energia é suficiente, se não for suficiente, seu RPI tentará usar muita corrente (amperagem) e desligará.Por outro lado, se você quiser usar scripts python, deverá ver o
joblib
que funciona melhor quando quiser paralelizar processos e, portanto, usará o número de processadores que deseja.fonte
Embora todas essas respostas estejam corretas de maneiras diferentes, é verdade que o sistema operacional usará automaticamente os diferentes núcleos para distribuir a carga. Você pode ver isso com um programa python simples (temp.py, por exemplo)
abra um terminal da área de trabalho RPi e digite o
$ top
que mostrará o trabalho do processador. Em seguida, abra outro terminal epython3 temp.py
você verá um trabalho python3 aumentar para 100% do tempo do processador. Em seguida, abra outro terminal e repita o processo e veja como você se move até 400%. Então, em um nível, como o @Shadow comentou, é simples e é o padrão. No entanto, projetar programas que podem usar o processamento paralelo não é trivial, como outros explicaram.fonte
A resposta é um sim retumbante! Você simplesmente tem que escrever seu programa para reconhecê-los e usá-los. Programas que fazem isso podem usar os núcleos. Eu escrevo o meu para fazer isso em Java e, portanto, posso.
As respostas acima dos desenvolvedores de Python têm um conceito muito limitado dessa resposta e, portanto, podem ser muito confusas, mas a resposta é SIM e apenas SIM!
fonte
Como o OP não especificou python em sua pergunta, gostaria de sugerir mais duas linguagens modernas que funcionam bem no Raspberry Pi e têm maneiras muito fáceis de usar a simultaneidade.
Meu favorito atual é o idioma Rust. Eu escrevi e compilei programas no Pi. A ferrugem é legal, pois evita muitos tipos de erros de ponteiro e condição de corrida, o que torna a escrita de código simultâneo mais fácil e segura. O Rust é uma linguagem de programação de sistemas, mas pode fazer praticamente qualquer coisa que C possa fazer.
Outro idioma é Go (também chamado Golang para facilitar a pesquisa). O Go foi criado pela equipe do Google e é uma linguagem razoavelmente madura. É fácil criar corotinas no Go, que eles chamam de "rotinas Go".
Ambos os idiomas podem compilar código no Raspberry Pi, até no Pi Zero. No entanto, ambos podem ser compilados em um computador mais rápido, o que é bom para programas grandes.
fonte