power management - Codificación de software eficiente de energía
power-management embedded (17)
En un dispositivo de sistema embebido portátil / portátil típico La duración de la batería es una preocupación importante en el diseño de H / W, S / W y las características que el dispositivo puede admitir. Desde la perspectiva de programación de software, uno conoce el código optimizado MIPS, memoria (datos y programas). Conozco el modo de suspensión profunda H / W, el modo de espera que se utilizan para sincronizar el hardware en ciclos inferiores o la vuelta del reloj por completo a algunos circutis no utilizados para ahorrar energía, pero estoy buscando algunas ideas desde ese punto de vista :
Donde mi código se está ejecutando y necesita seguir ejecutándose, dado esto, ¿cómo puedo escribir el código de "potencia" de manera eficiente para consumir un mínimo de vatios?
¿Existen construcciones de programación especiales, estructuras de datos, estructuras de control que debería tener en cuenta para lograr el mínimo consumo de energía para una funcionalidad determinada?
¿Hay consideraciones de diseño de alto nivel s / w que se deben tener en cuenta al momento del diseño de la estructura del código, o durante el diseño de bajo nivel para hacer que el código sea eficiente en términos de energía (menor consumo de energía) como sea posible?
Considere usar las interfaces de red lo menos que pueda. Es posible que desee recopilar información y enviarla en ráfagas en lugar de enviarla constantemente.
Mire lo que genera su compilador, especialmente para las áreas de código de acceso rápido.
No sondeas. Use eventos y otras primitivas del sistema operativo para esperar ocurrencias notificables. El sondeo asegura que la CPU permanecerá activa y usará más duración de la batería.
Según mi trabajo con teléfonos inteligentes, la mejor manera que he encontrado de preservar la duración de la batería es asegurar que todo lo que no necesite para que su programa funcione en ese punto específico está deshabilitado.
Por ejemplo, solo encienda Bluetooth cuando lo necesite, de manera similar las capacidades del teléfono, disminuya el brillo de la pantalla cuando no sea necesario, baje el volumen, etc.
La potencia utilizada por estas funciones generalmente superará con creces la potencia utilizada por su código.
Si tiene operaciones intermitentes de baja prioridad, no use temporizadores específicos para despertarse y lidiar con ellos, pero tenga en cuenta el procesamiento de otros eventos.
Usa la lógica para evitar situaciones estúpidas en las que tu aplicación podría irse a dormir por 10 ms y luego tener que volver a activarse para el siguiente evento. Para el tipo de plataforma mencionada, no debería importar si ambos eventos se procesan al mismo tiempo. Tener su propio mecanismo de temporizador y devolución de llamada podría ser apropiado para este tipo de toma de decisiones. La compensación es en complejidad y mantenimiento del código frente a los probables ahorros de energía.
Zeroith, usa una máquina totalmente estática que puede detenerse cuando está inactiva. No puedes vencer a cero Hz.
Primero, cambie a un programador de sistema operativo sin tickless. Despertarse cada milisegundo o así desperdicia poder. Si no puede, considere disminuir la interrupción del planificador en su lugar.
En segundo lugar, asegúrese de que su subproceso inactivo es un ahorro de energía, espere a la siguiente instrucción de interrupción. Puede hacer esto en el tipo de "sitio de usuario" poco regulado que tienen la mayoría de los dispositivos pequeños.
En tercer lugar, si tiene que sondear o realizar actividades de confianza del usuario, como actualizar la IU, dormir, hacerlo y volver a dormir.
No confíe en los marcos de GUI que no ha verificado para el tipo de código "dormir y girar". Especialmente el temporizador de eventos que puede estar tentado de usar para # 2.
Bloquee un hilo en lectura en lugar de sondear con select () / epoll () / WaitForMultipleObjects (). Pone énfasis en el scheuler de hilo (y su cerebro) pero los dispositivos generalmente funcionan bien. Esto termina cambiando un poco su diseño de alto nivel; se pone más ordenado !. Un ciclo principal que sondea todas las cosas que se pueden hacer es lento y derrochador en la CPU, pero garantiza el rendimiento. (Garantizado para ser lento)
Los resultados de la caché, crean cosas de forma perezosa. Los usuarios esperan que el dispositivo sea lento, así que no los decepcione. Menos correr es mejor. Corre tan poco como puedas. Los hilos separados pueden eliminarse cuando deja de necesitarlos.
Intente obtener más memoria de la que necesita, luego puede insertarla en más de una tabla hash y guardar la búsqueda. Esta es una compensación directa si la memoria es DRAM.
Observe un sistema en tiempo real de lo que cree que podría necesitar. Ahorra tiempo (sic) más tarde. También se las arreglan mejor con el enhebrado.
En pocas palabras, haz lo mínimo posible.
también algo que no es trivial es reducir la precisión de las operaciones matemáticas, buscar el conjunto de datos más pequeño disponible y, si está disponible, los datos del paquete del entorno de desarrollo y las operaciones agregadas.
Los libros de Knuth podrían proporcionarle toda la variante de los algoritmos específicos que necesita para ahorrar memoria o CPU, o ir con precisión reducida minimizando los errores de redondeo
también, dedicó algún tiempo a buscar toda la API del dispositivo integrado; por ejemplo, la mayoría de los teléfonos de Symbian podían hacer la codificación de audio a través de un hardware especializado
Bueno, en la medida en que su código pueda ejecutarse por completo en la caché del procesador, tendrá menos actividad de bus y ahorrará energía. En la medida en que su programa sea lo suficientemente pequeño como para caber los datos del código + por completo en la caché, obtendrá ese beneficio "gratis". OTOH, si su programa es demasiado grande y puede dividir sus programas en módulos que son más o menos independientes del otro, puede ahorrar algo de energía al dividirlo en programas separados. (Supongo que también es posible crear una cadena de herramientas que amplíe paquetes relacionados de código y datos en fragmentos del tamaño de la caché ...)
Supongo que, teóricamente, puede ahorrar una cierta cantidad de trabajo innecesario reduciendo el número de desreferenciación del puntero y refactorizando sus saltos para que los saltos más probables se tomen primero, pero eso no es realista como programador.
Transmeta tuvo la idea de dejar que la máquina hiciera algo de optimización de la instrucción sobre la marcha para ahorrar energía ... Pero eso no pareció ayudar lo suficiente ... Y mire dónde los atrapó.
Evitar las encuestas es una buena sugerencia.
El consumo de energía de un microprocesador es aproximadamente proporcional a su frecuencia de reloj y al cuadrado de su voltaje de suministro. Si tienes la posibilidad de ajustar estos desde el software, eso podría ahorrar algo de energía. Además, apagar las partes del procesador que no necesita (p. Ej. Unidad de coma flotante) puede ayudar, pero esto depende mucho de su plataforma. En cualquier caso, necesita una forma de medir el consumo de energía real de su procesador, para que pueda descubrir qué funciona y qué no. Al igual que las optimizaciones de velocidad, las optimizaciones de potencia deben perfilarse cuidadosamente.
Configure la memoria no utilizada o el flash en 0xFF no en 0x00. Esto es cierto para flash y eeprom, no estoy seguro acerca de s o d ram. Para los proms hay una inversión, por lo que un 0 se almacena como un 1 y consume más energía, un 1 se almacena como un cero y toma menos. Es por eso que lees 0xFFs después de borrar un bloque.
Haga su trabajo lo más rápido posible, y luego vaya a un estado inactivo esperando que ocurran interrupciones (o eventos). Intente hacer que el código se quede sin caché con el mínimo tráfico de memoria externo posible.
En Linux, instale powertop para ver con qué frecuencia el software despierta la CPU. Y siga los diversos consejos a los que se vincula el sitio powertop, algunos de los cuales probablemente también sean aplicables a sistemas que no sean Linux.
Elija algoritmos eficientes que son rápidos y tienen pequeños bloques básicos y mínimos accesos de memoria.
Comprenda el tamaño de la caché y las unidades funcionales de su procesador.
No accedas a la memoria. No use objetos o recolección de basura u otras construcciones de alto nivel si expanden su código de trabajo o conjunto de datos fuera de la caché disponible. Si conoces el tamaño de caché y la asociatividad, diseña todo el conjunto de datos de trabajo que necesitarás en el modo de bajo consumo y colócalo todo en el dcache (olvida algunas de las prácticas de codificación "adecuadas" que dispersan los datos en objetos o datos separados) estructuras si eso causa basura en la memoria caché). Lo mismo con todas las subrutinas. Ponga su código de trabajo establecido todo en un módulo si es necesario para rayarlo todo en el icache. Si el procesador tiene múltiples niveles de caché, trate de caber en el nivel más bajo de instrucción o caché de datos posible. No utilice la unidad de coma flotante ni ninguna otra instrucción que pueda encender otras unidades funcionales opcionales a menos que pueda argumentar que el uso de estas instrucciones acorta significativamente el tiempo que la CPU está fuera del modo de suspensión.
etc.
Bastante oportuno esto, artículo sobre Hackaday hoy sobre la medición del consumo de energía de varios comandos: Hackaday: el-efecto-de-código-en-el-consumo-de-energía
Aparte de eso:
- Las interrupciones son tus amigos
- Polling / wait () no son tus amigos
- Haz lo menos posible
- haga que su código sea lo más pequeño / eficiente posible
- Desactivar tantos módulos, pines, periféricos como sea posible en el micro
- Corre tan despacio como sea posible
- Si el micro tiene ajustes para la fuerza de la impulsión del perno, la velocidad de giro, etc., revíselos y configúrelos, los valores predeterminados son a menudo potencia máxima / velocidad máxima.
- volviendo al artículo anterior, regrese y mida el poder y vea si puede soltarlo alterando las cosas.
No sondee, duerma
Evite utilizar áreas con gran consumo de energía del chip cuando sea posible. Por ejemplo, los multiplicadores están hambrientos de poder, si puedes cambiar y agregar puedes ahorrar algunos Joules (¡siempre y cuando no hagas tanto cambio y añadas que en realidad el multiplicador es una ganancia!)
Si realmente lo dice en serio, obtengo un depurador de energía que puede correlacionar el uso de energía con su código fuente. Me gusta esto
- Como dijo
1800 INFORMATION
, evite las encuestas; suscribirse a eventos y esperar a que sucedan - Actualice el contenido de la ventana solo cuando sea necesario; deje que el sistema decida cuándo volver a dibujarlo
- Al actualizar el contenido de la ventana, asegúrese de que su código vuelva a crear la menor cantidad posible de la región no válida.
- Con el código rápido, la CPU vuelve al modo de suspensión profunda más rápido y hay una mayor probabilidad de que dicho código permanezca en caché L1.
- Opere con datos pequeños al mismo tiempo para que los datos permanezcan en cachés también
- Asegúrese de que su aplicación no realice ninguna acción innecesaria cuando esté en segundo plano
- Haga que su software no solo sea eficiente en términos de consumo de energía, sino también consciente de la energía: actualice los gráficos con menos frecuencia cuando tenga batería, deshabilite las animaciones, menos agallas en el disco duro
Y lea algunas otras pautas . ;)
Recientemente, comenzó a aparecer en los blogs de software de Intel una serie de publicaciones tituladas "Optimización de aplicaciones de software para energía" . Puede ser de alguna utilidad para desarrolladores x86.