Me preguntaba si hay una manera simple de "encender" todo el 100% de la CPU para que pueda ejecutar procesos más rápido (como los cálculos de Python).
1) ¿Es esto posible?
2) ¿Hay alguna manera fácil de volver a la normalidad?
3) ¿Hay alguna manera de usar menos CPU si lo desea?
Estoy pensando en una interacción de línea de comando como:
pi@raspberry:~ $ sudo turnOnFourCores python run.py
Respuestas:
Por defecto, cualquier computadora intentará usar todos sus núcleos cuando pueda. Sin embargo, solo puede lograr esto cuando una aplicación es multiproceso. Si no lo es (es decir, un script de Python que no usa el
threading
módulo), entonces solo puede usar, como máximo, un núcleo. Esto equivale al 25% de la CPU en una CPU de cuatro núcleos. Si desea modificar su secuencia de comandos para usar múltiples núcleos, puede dividir su cálculo en varias partes y realizar varios subprocesos como se muestra en la documentación de Python .Actualizar:
Como respondió Anon , esto no funcionará sin trabajar con GIL (Global Interpreter Lock) de Python. Esto permite que las tareas funcionen (aparentemente) al mismo tiempo, pero no permite que el código se ejecute en múltiples núcleos. Si está utilizando módulos escritos en C (por ejemplo, numpy), pueden permitirle usar múltiples núcleos para superar esa limitación. Además, si esa no es una opción, Python ofrece multiprocesamiento , que le permite ejecutar cualquier tarea en múltiples núcleos.
fuente
No en el sentido de que creo que estás insinuando. Este no es un problema específico de pi, tampoco, es una restricción lógica.
Por sí mismas, las computadoras actualmente no tienen mucha capacidad para determinar que un proceso que se ejecuta como un solo subproceso puede ejecutarse en paralelo. Tenga en cuenta que en el momento en que podrían tener esta capacidad, no habría necesidad de programadores informáticos, porque un sistema informático que podría hacer esto también podría escribir su propio código 1 ..
Considere la siguiente expresión matemática simple:
Existe cierto potencial para que esto se calcule en paralelo, pero es lógicamente limitado. Yo diría que no tiene sentido en más de dos hilos, e incluso en su mayoría solo será uno:
El hilo # 2 ha contribuido calculando 3 + 6 = 9, usado en el paso C por el hilo # 1, guardándolo en un paso. Pero eso es lo más lejos que llegará el paralelismo útil. Mientras que el hilo # 2 podría calcular 17/9 mientras que el # 1 está haciendo 6 * 17, hacerlo sería inútil, porque ahora tiene dos caminos diferentes hacia el mismo objetivo que no pueden ser recombinados. Es decir, el # 2 podría seguir funcionando:
Y terminan con el mismo resultado que el hilo # 1 (11.333), pero no se han ayudado entre sí más allá del paso A, por lo tanto, hacer que dos de ellos persigan este objetivo es una pérdida de tiempo.
(Tenga en cuenta que este ejemplo no es literal; tiene la intención de demostrar un principio lógico. La escala en la que se enhebran las tareas en el código de usuario es mucho mayor, pero no necesita una verdadera lección en programación de subprocesos múltiples para capta la idea aquí.)
La explotación de múltiples procesadores requiere un código escrito para hacerlo. No puedes simplemente tomar nada y decir: "¡oh, usa los 4 núcleos y hazlo más rápido!". Eso no es lo que sucedería. Lógicamente, muchos (... o la mayoría) de los problemas y tareas implican pasos que no pueden suceder en paralelo, deben suceder en secuencia.
1. Pero vea el comentario de Felix Dombek a continuación; No soy un experto en IA. También vale la pena señalar que, según los comentarios de Peter Corde, los sistemas de instrucción y procesadores contemporáneos pueden ser explotados por el sistema operativo para optimizar cosas muy finas de forma paralela, y las tuberías de hardware también lo hacen, aunque no entre núcleos (un solo core tiene más de una cosa en funcionamiento, operando en la secuencia de instrucciones en varios puntos antes de su ejecución final). Estaba tratando de seguir el tema de los hilos de los usuarios aquí, ya que creo que eso es más o menos a lo que te estás refiriendo.
fuente
add
instrucciones una al lado de la otra para que ambos puedan ejecutarse en el mismo ciclo de reloj Sin embargo, el siguiente resto de multiplicación y división se serializará por dependencias de datos, como usted señala.No para python.
Otras personas le sugieren que estudie los subprocesos, que es una respuesta válida para la mayoría de los idiomas, pero no tuvieron en cuenta que está utilizando python.
Python GIL no le permite hacer uso efectivo de múltiples núcleos.
fuente
El uso de múltiples núcleos requiere exponer explícitamente el paralelismo de nivel de subproceso al sistema operativo, que generalmente requiere que el programador escriba un programa de subprocesos múltiples. (O para ejecutar un programa de subproceso único varias veces en diferentes entradas, como compilar con
make -j4
)Sin embargo, los compiladores para algunos idiomas admiten la paralelización automática. Por ejemplo, C o C ++ con OpenMP puede compilar un
for()
bucle ordinario en un programa que inicia múltiples subprocesos.Pero aún así, esto tiene que suceder cuando escribió o compiló el programa. No hay forma de que el hardware y los sistemas operativos actuales usen múltiples núcleos para acelerar un programa de subproceso único.
Relacionado: ¿Cómo se ejecuta un solo hilo en múltiples núcleos? : respuesta: no lo hacen. Pero hay otros tipos de paralelismo, como el paralelismo de nivel de instrucción que un solo núcleo de CPU encuentra y explota para ejecutar un solo hilo más rápido que una instrucción a la vez.
Mi respuesta a esa pregunta entra en algunos de los detalles de cómo las CPU modernas encuentran y explotan el paralelismo de nivel de instrucción de grano fino. (Principalmente centrado en x86). Eso es solo parte de cómo funcionan las CPU normales, al tener varias instrucciones en vuelo a la vez, y no es algo que necesite habilitar especialmente. (Sin embargo, hay contadores de rendimiento que le permiten ver cuántas instrucciones por reloj logró ejecutar su CPU mientras ejecutaba un programa u otras medidas).
Tenga en cuenta que RPi3 utiliza núcleos de CPU ARM Cortex-A53 en orden . Cada núcleo es superescalar de ancho 2 (2 instrucciones por reloj como lo permite ILP), pero no puede reordenar las instrucciones para encontrar más paralelismo a nivel de instrucción y ocultar latencia.
Aún así, la CPU está canalizada, por lo que el número total de instrucciones en vuelo (desde recuperar y decodificar hasta la etapa de reescritura al final de la canalización) es significativo. Cuando las dependencias de datos no limitan las cosas, puede haber 2 instrucciones en cada etapa de canalización en las que la CPU está trabajando, con un rendimiento de 2 instrucciones por reloj. (Eso es lo que significa 2 ancho).
No puede ejecutar instrucciones fuera de orden, pero con un orden de instrucciones cuidadoso (generalmente por un compilador) aún puede ocultar la latencia de una instrucción que toma varios ciclos para que su salida esté lista. (por ejemplo, una carga incluso si llega a la memoria caché o una multiplicación tomará varios ciclos, en comparación con una adición que esté lista el próximo ciclo). El truco consiste en ordenar las instrucciones asm para que haya múltiples instrucciones independientes entre la que produce un resultado y la que lo utiliza.
Tener software (un compilador) para programar las instrucciones estáticamente es más frágil que tener hardware que puede reordenarse internamente mientras se preserva la ilusión de ejecutarse en orden de programa. Es muy difícil para los compiladores hacer un trabajo tan bueno como incluso una pequeña ventana fuera de orden para reordenar las instrucciones porque los errores de caché son impredecibles, y es difícil analizar las cadenas de dependencia a través de las llamadas a funciones en tiempo de compilación. Y el número de registros es limitado sin cambiar el nombre del registro de hardware.
Todo esto es una pequeña comodidad cuando su código se ejecuta más lentamente de lo que desea. Claro que hay muchas cosas interesantes debajo del capó en un Cortex-A53, pero hay más cosas geniales debajo del capó en un Cortex-A57 (como la ejecución fuera de orden de hasta 3 instrucciones por reloj), e incluso más en una gran CPU x86 como Skylake (sin mencionar las diferencias de velocidad de reloj).
Cortex-A53 es bastante fantástico en comparación con un https://en.wikipedia.org/wiki/Classic_RISC_pipeline como MIPS original sobre el que aprendería en la clase de arquitectura de computadora, pero según los estándares modernos es bastante bajo.
fuente
java
no lo esmyapp.jar
, y ciertamente no es de un solo subproceso.Así no es como funcionan las CPU ... en absoluto.
Tal como está actualmente, su CPU es perfectamente capaz de funcionar al 100% de uso, suponiendo que no se está acelerando debido a problemas relacionados con la temperatura a 80 grados Celsius o más. Dicho esto, no (en general) desea ver su CPU vinculada al 100%. Si habitualmente utiliza el 100% de la CPU, es probable que tenga demasiado para su procesador. Esto causará tartamudeo y una experiencia de usuario generalmente infeliz.
Para comparar con algo más físico, la utilización de su CPU se parece mucho a un automóvil. Es probable que el automóvil sea capaz de avanzar 100 mph, pero hay una buena probabilidad de que su velocímetro lea algo significativamente debajo de eso. Cuando estés en la ciudad, es posible que nunca puedas alcanzar las 25 mph. Sin embargo, eso no cambia que el automóvil pueda ir a 100 mph. Simplemente no has presionado el acelerador lo suficientemente fuerte.
Si simplemente hace que el RPi haga más cosas (presione más en el acelerador), verá que la cifra de utilización de la CPU aumenta. Por ejemplo, observe la utilización de la CPU cuando ejecuta el comando
yes
en una ventana de terminal (recuerde quectrl+c
finaliza los comandos de terminal). Esto aumentará su CPU en un 25%, ya que maximiza uno de sus cuatro núcleos de CPU.fuente
Las otras respuestas dan buenos detalles, pero no parecen abordar sus preguntas específicamente.
NB:
Si está buscando mejorar el rendimiento del pi en general, es posible que desee considerar Overclocking. Esto permite que la CPU funcione a un ritmo más rápido. Las desventajas son una mayor producción de calor, una menor vida útil del procesador y un mayor consumo de energía.
fuente
Si es posible, parametrizaría el script y los ejecutaría en procesos separados de Python. Por ejemplo:
Otra alternativa es la biblioteca de multiprocesamiento ya mencionada, que le permite bifurcar y unir procesos de Python. Pero eso también requiere que tenga una lista de parámetros (como un nombre de archivo) para los que desea que se ejecuten los cálculos.
fuente
map
pero aparentemente también tiene muchas construcciones de memoria compartida bastante sofisticadas.Creo que OP podría no comprender completamente los conceptos de programación multi-core / multi-thread y cuán difícil es utilizar completamente el 100% de multi-core a menos que el algoritmo pueda convertirse fácilmente en un problema embarazosamente paralelo .
Para obtener más información, puede leer más sobre el conocido título del artículo "Se acabó el almuerzo gratis" http://www.gotw.ca/publications/concurrency-ddj.htm
fuente
Si quieres probar tu RPI. Puede ejecutar
stress
como aquí , luego puede ver cómo se utilizan sus CPUhtop
. Esto es útil porque puede ver si su fuente de energía es suficiente, si no es suficiente, su RPI intentará usar demasiada corriente (amperaje) y se apagará.Por otro lado, si desea utilizar secuencias de comandos de Python, debería ver
joblib
qué funciona muy bien cuando desea paralelizar procesos, y por lo tanto utilizará la cantidad de procesadores que desee.fuente
Aunque todas estas respuestas son correctas de diferentes maneras, es cierto que el sistema operativo utilizará automáticamente los diferentes núcleos para distribuir la carga. Puede ver esto con un simple programa de Python (temp.py say)
abra una terminal desde su escritorio RPi y escriba
$ top
lo que mostrará el trabajo del procesador. Luego abra otra terminal ypython3 temp.py
verá que un trabajo de python3 aumenta al 100% del tiempo de procesador. Luego abra otra terminal y repita el proceso y vea cómo se mueve hasta el 400%. Entonces, en un nivel como comentó @Shadow, es así de simple y es el valor predeterminado. Sin embargo, el diseño de programas que pueden usar el procesamiento paralelo no es trivial como otros han explicado.fuente
¡La respuesta es un sí rotundo! Simplemente tiene que escribir su programa para reconocerlos y usarlos. Los programas que hacen esto pueden usar los núcleos. Escribo el mío para hacer esto en Java y así puedo.
Las respuestas anteriores de los desarrolladores de Python tienen un concepto muy limitado de esta respuesta, por lo que pueden ser muy confusas, ¡pero la respuesta es SÍ y solo SÍ!
fuente
Dado que el OP no especificó Python en su pregunta, me gustaría sugerir dos lenguajes modernos más que funcionen bien en la Raspberry Pi y que tengan formas muy fáciles de usar la concurrencia.
Mi favorito actual es el lenguaje Rust. He escrito y compilado programas en el Pi. Rust es bueno porque evita muchos tipos de errores de puntero y condición de carrera, lo que hace que escribir código concurrente sea más fácil y seguro. Rust es un lenguaje de programación de sistemas, pero puede hacer casi cualquier cosa que C pueda hacer.
Otro lenguaje de este tipo es Go (también llamado Golang para facilitar la búsqueda). Go fue creado por el equipo de Google y es un lenguaje razonablemente maduro. Es fácil hacer corutinas en Go, a las que llaman "rutinas Go".
Ambos lenguajes pueden compilar código en Raspberry Pi, incluso el Pi Zero. Sin embargo, ambos se pueden compilar en forma cruzada desde una computadora más rápida, lo cual es bueno para programas grandes.
fuente