Universidad Nacional del Centro de la Provincia De Buenos Aires Facultad de Ciencias Exactas - Departamento de Computación y Sistemas Doctorado en Ciencias de la Computación Reducción de consumo energético en aplicaciones científicas para dispositivos móviles a través de refactorización de código fuente Ing. Ana Victoria Rodríguez Director: Dr. Alejandro Zunino Co-Director: Dr. Cristian Mateos Tesis presentada como requisito parcial para optar por el título de Doctor en Ciencias de la Computación Noviembre 2017
175
Embed
Reducción de consumo energético en aplicaciones científicas ...
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Universidad Nacional del Centro de la Provincia De Buenos Aires
Facultad de Ciencias Exactas - Departamento de Computación y Sistemas
Doctorado en Ciencias de la Computación
Reducción de consumo energético en aplicaciones científicas paradispositivos móviles a través de refactorización de código fuente
Ing. Ana Victoria RodríguezDirector: Dr. Alejandro Zunino
Co-Director: Dr. Cristian Mateos
Tesis presentada como requisito parcial
para optar por el título de
Doctor en Ciencias de la Computación
Noviembre 2017
Resumen
La llegada de ambientes de cómputo que representan nuevos paradigmas de compu-
tación como los grid móviles y los clouds móviles, junto con el creciente número de dis-
positivos móviles con capacidades cada vez más potentes hace este tipo de dispositivos
atractivos para los usuarios que ejecutan aplicaciones científicas y de HPC. Sin embar-
go, los dispositivos móviles aún tienen capacidades limitadas en comparación con otros
dispositivos como PCs y sobre todo servidores, generando obstáculos para desarrollar
software que aproveche las mismas. Aún más importante a la hora de realizar desarrollos
móviles es tener en cuenta que los dispositivos móviles dependen de las baterías para su
suministro de energía, por lo que los usuarios descartan las aplicaciones que afectan sig-
nificativamente la duración de las mismas. Como resultado, aparece un nuevo requisito
no funcional al momento de desarrollar aplicaciones para dispositivos móviles: consumo
energético.
Comúnmente, los desarrolladores no saben cuánta energía consumen los diferentes com-
ponentes de hardware y el software. Entonces, a pesar de que estén capacitados para
desarrollar software, necesitan pautas y conocimientos específicos para desarrollar apli-
caciones eficientes energéticamente. Para atacar este problema, esta tesis de doctorado es-
tudia cómo reducir el consumo de energía en dispositivos móviles a través de refactoriza-
ción de código fuente. Específicamente, investigamos este problema en el contexto de los
núcleos computacionales intensivos recurrentes en aplicaciones científicas pero sin dejar
de lado la posibilidad de extender los resultados a otras áreas. Particularmente, este es-
tudio conlleva a contribuciones no sólo en el desarrollo de software móvil, sino también
en el área de Green Computing.
Para lograr el objetivo de este trabajo primero debemos delimitar el estudio a un sistema
operativo (SO) específico y un lenguaje específico ya que el comportamiento energético
varía de acuerdo al SO, el lenguaje y el hardware, entre otras variables. Entonces, lue-
go de evaluar diferentes sistemas operativos y lenguajes, decidimos utilizar dispositivos
móviles Android –el sistema operativo móvil más popular a nivel mundial– y desarro-
llar el estudio en Java, el lenguaje de alto nivel de Android. En un segundo paso, pre-
sentamos los trade-off entre el esfuerzo de análisis y refactorización necesario frente a
la ganancia (en términos de energía) para cada refactorización, junto con el impacto en
el diseño de la aplicación generado por aplicar estos refactorings. Además, se analizan
los inconvenientes inherentes al uso de dispositivos móviles para la ejecución de códigos
computacionalmente intensivos, limitando la investigación a teléfonos inteligentes y ta-
bletas. La elección de Java, además, propicia el análisis del desempeño de los refactorings
en desarrollo de aplicaciones científicas que corren en servidores, donde el uso de Java es
altamente difundido.
En resumen, la evaluación del enfoque apunta a medir el consumo energético de di-
ferentes versiones de varios grupos de micro-benchmarks que representan operaciones
primitivas comunes en aplicaciones científicas. Basándonos en el análisis de estas evalua-
ciones de micro-benchmarks derivamos guías de buenas prácticas para que los desarro-
lladores puedan aplicar las abstracciones de programación más eficientes desde el punto
de vista energético en sus aplicaciones. Además, generamos guías prácticas para refac-
torizar aplicaciones existentes, propiciando así una reducción en su consumo energético.
Finalmente, evaluamos y analizamos el impacto de tales refactorizaciones en aplicaciones
móviles con uso intensivo de CPU. En todos nuestros experimentos utilizamos variedad
de dispositivos móviles para obtener más generalidad al obtener los resultados ya que
el consumo energético de una operación puede variar de acuerdo al hardware de cada
dispositivo. Además, presentamos los resultados de los trabajos realizados sobre servi-
dores con la finalidad de comparar el impacto obtenido en los diferentes ambientes de
En el siguiente paso, identificamos 8 diferentes operaciones comunes para evaluar: Co-pia de matrices, Creación de Objetos, Acceso a Atributos, Manejo de Strings, Manejo deExcepciones, Uso de Tipos de Dato Primitivos, Recorrido de Matrices y Operaciones Arit-méticas Rodriguez et al. [2016a]. Para cada grupo de micro-benchmarks, programamosal menos dos versiones diferentes que ejecutamos varias veces en diferentes dispositivosAndroid con el fin de obtener generalidad en nuestros resultados. El siguiente párraforesume las razones principales por las cuales estos grupos fueron seleccionados.
En primer lugar, teniendo en cuenta que se han desarrollado diferentes bibliotecas para
uso científico en diversos lenguajes OO como C++ y Java Hofschuster and Krämer [2004],
Papadimitriou et al. [2011], comparamos la mejora del consumo de energía utilizando di-
chas bibliotecas para copiar una matriz en contra de implementar la misma funcionalidad
manualmente.
Además, elegimos la creación de objetos porque los objetos son el foco de la programa-
ción OO, así como su creación es una de las razones para la disminución del rendimiento
de la aplicación. Esta disminución del rendimiento se debe a las costosas tareas de ad-
ministración de memoria que esto implica, por ejemplo, el Garbage Collector en Java o
la eliminación de objetos explícitos en C++ que recuperan la memoria de los objetos no
utilizados. Como resultado, una cantidad excesiva de objetos puede disminuir el rendi-
miento de la aplicación. Por lo tanto, reutilizar un objeto previamente creado podría ser
una buena práctica para ahorrar energía en una aplicación.
El siguiente grupo, Acceso a atributos, se eligió por motivos similares: en la programa-
ción OO, un método es una subrutina asociada a una clase, siendo la llamada a un método
una operación común en aplicaciones OO. Esto nos llevó a analizar el consumo de ener-
gía del acceso a atributos de una clase a través de métodos, utilizados para preservar el
encapsulamiento de objetos, contra la ejecución de la misma funcionalidad sin la llamada
al método.
Con respecto a la manipulación de Strings, la concatenación de Strings es la operación
más frecuente Christensen et al. [2003]. De hecho, existen varios trabajos que investigan
problemas relacionados con la concatenación eficiente de Strings. Por ejemplo, Hermelin
et al. [2008] analiza el problema de cubrir un conjunto de Strings S con un conjunto C de
subcadenas en S (C cubre S si cada cadena en S se puede escribir como una concatenación
de las subcadenas en C). Como resultado, nuestro trabajo evalúa el consumo de energía
de diferentes operaciones para concatenar Strings.
Por lo tanto, las excepciones representan un mecanismo para el manejo de errores de for-
ma correcta y se usan comúnmente en los lenguajes que las soportan. Sin embargo, las
excepciones producen consumos generales que disminuyen el rendimiento de la aplica-
ción. En consecuencia, trabajos como Lee and Jeon [2010] analizan los mecanismos para
eliminar los overheads generales provocados por el manejo de excepciones y nos motivan
a medir el impacto de uso de excepciones en el consumo de energía. En otras palabras,
7
medimos el consumo de energía de diferentes métodos para gestionar un error, como
lanzar una excepción y manejar el error manualmente.
Cuando las aplicaciones usan wrappers para representar datos numéricos se utiliza más
memoria que si utilizaran los tipos de datos primitivos. Esto es porque los tipos de datos
primitivos usan la cantidad mínima de bits necesarios para representar su valor mientras
que los wrappers proveen operaciones particulares además de una estructura interna.
Luego, discutiremos las ventajas en términos de uso de energía del uso de tipos de datos
primitivos contra el uso de wrappers.
Por otra parte, las matrices son una estructura común en el software científico que tienen
numerosos usos matemáticos y computacionales importantes. Por ejemplo, las transfor-
maciones tridimensionales basadas en matrices Barisone et al. [2001] y las multiplicacio-
nes matriciales son núcleos importantes en algoritmos de álgebra lineal. entonces, eva-
luamos el consumo de energía de atravesar una matriz por filas y columnas.
El último grupo se refiere a la precisión al manipular datos numéricos. En cuanto a opera-
ciones aritméticas, históricamente varios estudios Vaidya [1990], Baron et al. [2006], Gur-
ram and Agarwal [2007] han centrado sus esfuerzos en optimizarlas. Dado que la suma
es la operación aritmética más común que los procesadores realizan3, nosotros decidimos
medir el consumo de energía al sumar datos de tipo float, int, double y long.
Después de analizar los resultados de micro-benchmarks (Q1), estudiaremos las guías
para programar estas operaciones comunes en dispositivos móviles de forma eficiente
en términos de energía, analizando también su impacto en aplicaciones científicas reales
(Q2). Sin embargo, como mencionamos anteriormente, seguir estas pautas puede violar
los principios conocidos del paradigma OO y, por lo tanto, una nueva pregunta de in-
vestigación será (Q3): ¿es posible explotar refactorizaciones de código obtenidas minimi-
zando el impacto en la calidad del código según lo estipulado por los criterios de calidad
tradicionales? Luego, analizaremos los resultados de micro-benchmark y la hipótesis so-
bre la calidad del software en diferentes aplicaciones científicas reales. Como extensiones
evidentes y simples, evaluaremos estos experimentos en servidores (Q4), generalizando
los resultados de nuestro trabajo en consumo de energía; y evaluaremos estas refactori-
zaciones propuestas en aplicaciones móviles reales para usuarios (Q5).
Finalmente, la principal contribución de esta tesis serán la guía de buenas prácticas y una
lista de refactorizaciones para desarrollar aplicaciones científicas adecuadas para ser eje-
cutadas en dispositivos móviles consumiendo la menor cantidad de energía posible. Esto
posiciona la contribución no solo en la programación móvil sino también en la informáti-
ca distribuida móvil, donde las aplicaciones distribuidas envían tareas a los dispositivos
en función de su capacidad energética, integrando dispositivos móviles adecuados en
entornos distribuidos como nodos activos. Aplicar nuestras pautas significa ejecutar ta-
reas que son eficientes energéticamente en los dispositivos que dependen de su batería
como fuente de energía. Además, esta investigación doctoral tiene un impacto en Green
Computing, un área cuyo objetivo principal es reducir el consumo de energía, reducir el
uso de materiales peligrosos al fabricar componentes de hardware y promover el recicla-
miento o biodegradación de dichos materiales.
1.3. Organización
Este Capítulo concluye presentando la organización general del trabajo. El Capítulo 2
describe el contexto del trabajo, teniendo en cuenta tanto las tecnologías utilizadas como
las áreas con las cuales el objetivo de este trabajo está directamente relacionado. Especi-
ficamente, el Capítulo 2 introduce en detalle las nociones de desarrollo de software para
dispositivos móviles, acompañadas por las principales características de estos dispositi-
vos y el papel que desempeñan hoy en día específicamente en el desarrollo de aplicacio-
nes científicas.
Además, el Capítulo 3 presenta y discute trabajos afines a nuestra hipótesis y nuestras
contribuciones. Estos trabajos cubren tanto el área de desarrollo de aplicaciones móvi-
les como la integración de dispositivos móviles a estructuras computacionales con fines
científicos. Además se presentan trabajos de ahorro energético en servidores.
Posteriormente, el Capítulo 4 presenta los diferentes grupos de micro-benchmarks queserán utilizados para trabajar con aplicaciones científicas. En este capítulo presentamosuna explicación detallada de cada decisión que se tomó durante el desarrollo de estetrabajo. Estas decisiones no solo se refieren a la elección de los dispositivos, el sistemaoperativo y el desarrollo del lenguaje, sino también a qué grupos de micro-benchmarksy aplicaciones se evalúan y por qué.
Luego, el Capítulo 5 discute la metodología utilizada para los experimentos junto con los
problemas que se tuvieron que enfrentar, particularmente cómo obtener mediciones de
energía precisas. Como consecuencia, presentamos diferentes opciones para sortear estos
problemas junto con la decisión final y su justificación.
Los resultados de los experimentos junto con sus características se presentan en el Capí-tulo 6, donde se agregan el análisis detallado junto con las conclusiones sobre los mismos.El objetivo de este Capítulo es evaluar el impacto en términos de ahorro de energía delas buenas prácticas propuestas y, por lo tanto, validar empíricamente nuestra hipótesisprincipal de investigación.
Finalmente, el Capítulo 7 profundiza las conclusiones que se desarrollaron a partir deltrabajo completo. Además, este último capítulo presenta una breve discusión sobre lostrabajos futuros que se llevarán a cabo continuando con la línea de investigación.
9
10
Capıtulo 2
Background
Este capítulo explica los conceptos principales sobre la construcción de este trabajo. Porlo tanto, hacemos una breve descripción de Android, el sistema operativo elegido parallevar a cabo nuestro análisis y experimentos. Junto con esta descripción, se presenta unresumen del desarrollo de aplicaciones de Android en la Sección 2.2. Finalmente, despuésde la introducción general, los temas importantes asociados a este trabajo se discuten endetalle: el uso de dispositivos móviles para la ejecución de código intensivo, la integra-ción de ellos en las infraestructuras computacionales distribuidas, y la contribución deeste trabajo en el área de Green Computing .
En particular, como el trabajo evalúa aplicaciones científicas ejecutadas en dispositivos
móviles, la Sección 2.3 muestra que es posible ejecutar aplicaciones que requieren una
gran capacidad de cómputo en Smartphones. Como los dispositivos móviles son ade-
cuados para ejecutar tareas intensivas, se pueden integrar en entornos distribuidos como
Grids los cuales se presentan en la Sección 2.4. Este tipo de entorno se presenta porque
nuestra investigación puede contribuir a esa área a través de la generación de pautas
para integrar correctamente dispositivos móviles. Por último, la Sección 2.4 introduce
el concepto de Green Computing. El área de Green Computing busca reducir el impacto
ambiental de las computadoras y los recursos relacionados. Entonces, reducir el consumo
de energía en cualquier dispositivo contribuye directamente con Green Computing.
2.1. Android
Android es un sistema operativo de código abierto diseñado para dispositivos móvilesdesarrollado por Google y basado en un kernel de Linux. Tiene un middleware extensi-ble y aplicaciones de usuario clave. Además, proporciona una tienda de aplicaciones enla que hay más de 2.000.000 de aplicaciones, de las cuales más de dos tercios son gra-tuitas. Esto permite a los usuarios finales personalizar sus dispositivos. Otra forma depersonalizar dispositivos es desarrollar aplicaciones personalizadas utilizando Java, ellenguaje de alto nivel utilizado en Android. Para ejecutar tales aplicaciones, Android usa
11
Figura 2.1: Arquitectura de Android
una máquina virtual especial optimizada para este tipo de dispositivos. Finalmente, An-droid presenta una arquitectura en capas -Figura 2.1- donde cada capa usa los serviciosofrecidos por las anteriores, y ofrece sus propios servicios a las capas superiores.
Los siguientes párrafos presentan una breve descripción de cada una de las capas de laarquitectura de Android:
Linux Kernel: la base de la plataforma de Android es el kernel de Linux. Por ejem-
plo, Android Runtime (ART) se basa en el kernel de Linux para funcionalidades
como el manejo de la memoria y el subprocesamiento. El uso de un kernel de Linux
le permite a Android aprovechar las características claves de seguridad y permi-
te a los fabricantes de dispositivos desarrollar controladores de hardware para un
kernel conocido.
12
Hardware Abstraction Layer (HAL): HAL proporciona interfaces estándar que ex-ponen las capacidades de hardware del dispositivo. La HAL consta de múltiplesmódulos de biblioteca, cada uno de los cuales implementa una interfaz para un ti-po específico de componente de hardware, como la cámara o el bluetooth. Cuandouna API realiza una llamada para acceder a un hardware de un dispositivo espe-cífico el sistema Android carga el módulo de biblioteca para ese componente dehardware particular.
Android Runtime (ART): Para dispositivos con Android versión 5.0 (API nivel 21) osuperior, cada aplicación se ejecuta en su propio proceso y con su propia instanciade ART. ART está diseñado para ejecutar múltiples máquinas virtuales en dispo-sitivos de poca memoria mediante la ejecución de archivos DEX, un formato debytecode diseñado especialmente para Android optimizado para minimizar el usode memoria. Algunas de las principales características de ART incluyen lo siguien-te:
• Compilación Ahead-of-time (AOT) and just-in-time (JIT)
• Optimización de garbage collection (GC)
• Mejor soporte de depuración, incluido un generador de perfiles de muestreodedicado, diagnostico detallado de excepciones e informes de fallas, y la capa-cidad de establecer watchpoints
Antes de Android versión 5.0 (API nivel 21), Dalvik era el la máquina virtual de An-droid. Si la aplicación funciona bien con ART, entonces debería funcionar tambiénen Dalvik, pero puede que no sea cierto lo contrario. Android también incluye unconjunto de bibliotecas de tiempo de ejecución del núcleo que proporcionan la ma-yoría de las funcionalidades del lenguaje de programación Java, incluidas algunascaracterísticas del lenguaje Java 8.
Native C/C++ Libraries: Muchos componentes y servicios centrales del sistemade Android, como ART y HAL, se crean a partir de código nativo que requierebibliotecas nativas escritas en C y C++. La plataforma Android proporciona Javaframework APIs para exponer la funcionalidad de algunas de estas bibliotecas na-tivas a las aplicaciones. Por ejemplo, los desarrolladores pueden acceder a OpenGLES a través del framework de Android Java OpenGL API para agregar soporte pa-ra dibujar y manipular gráficos 2D y 3D en las aplicaciones. Además, cuando losdesarrolladores están implementando una aplicación que requiere código C o C++,pueden usar el Kit de desarrollo nativo de Android (NDK) para acceder a algunasde estas bibliotecas de plataforma nativa desde su código.
Java API Framework: Todo el conjunto de funciones del SO Android está dispo-nible para los desarrolladores a través de API escritas en Java. Estas API formanlos bloques que los desarrolladores necesitan para crear aplicaciones Android quesimplifiquen la reutilización de componentes y servicios centrales y modulares delsistema. Tales bloques incluyen:
13
• Los desarrolladores pueden utilizar un sistema de visualización extensiblespara desarrollar interfaces de usuario en sus aplicaciones, incluyendo listas,tablas, cuadros de texto, botones e incluso un navegador web.
• Un administrador de recursos, que proporciona acceso a recursos tales comográficos y archivos de diseño.
• Un administrador de notificaciones que permite que todas las aplicacionesmuestren alertas personalizadas en la barra de estado.
• Un administrador de actividades que gestiona el ciclo de vida de las aplicacio-nes y proporciona una pila de navegación entre actividades común.
• Content Providers que permiten a las aplicaciones acceder a datos de otrasaplicaciones, como acceder a la información de la aplicación Contactos, o com-partir sus propios datos.
Los desarrolladores tienen acceso completo a las mismas APIs que utilizan las apli-caciones del sistema Android.
System Apps: Android viene con un conjunto de aplicaciones para correo electróni-co, mensajes SMS, agenda, navegación por Internet, contactos, etc. Las aplicacionesincluidas con la plataforma no tienen un estado especial comparado con las aplica-ciones que el usuario elige instalar. Por lo tanto, una aplicación de terceros puedeconvertirse en el navegador web predeterminado del usuario, SMS Messenger oincluso en el teclado predeterminado (se aplican algunas excepciones, como la apli-cación de Configuración del sistema).
Las aplicaciones del sistema funcionan como aplicaciones para los usuarios y co-
mo proveedoras de capacidades clave a las que los desarrolladores pueden acceder
desde su propia aplicación. Por ejemplo, si una aplicación desea entregar un mensa-
je SMS, los desarrolladores no necesitan construir esa funcionalidad ellos mismos,
sino que pueden invocar cualquier aplicación de SMS que ya esté instalada para
entregar un mensaje.
Además de estas características técnicas, es importante destacar que la popularidad deAndroid ha crecido exponencialmente1 desde su lanzamiento debido a que hace a losdispositivos más adaptables a las necesidades de los usuarios y, en consecuencia, los ha-ce más útiles. Además, debido a que Android es open source, los desarrolladores puedencrear una experiencia móvil con personalización única de dispositivos. Además de es-to, Android ofrece herramientas para crear aplicaciones. Las herramientas de desarrollopara Android proporcionan un IDE completo para Java con funciones avanzadas parael desarrollo de aplicaciones móviles. Con el IDE, los usuarios pueden desarrollar apli-caciones para cualquier dispositivo Android o crear dispositivos virtuales que emulencualquier configuración de hardware compatible para probar sus aplicaciones.
Finalmente, la API de Android tiene diferentes versiones disponibles que han sido desa-rrolladas de acuerdo a las necesidades emergentes. Por lo tanto, los cambios realizados
entre versiones generalmente son nuevas funcionalidades o reemplazos de funcionali-dades anteriores. Estas versiones actualizadas están diseñadas para ser compatibles conversiones anteriores, dejando las funcionalidades antiguas en desuso pero no elimina-das. Solo en un pequeño porcentaje de casos, algunas funcionalidades de la API fueroneliminadas. Cada versión de Android admite exactamente un nivel de API, que admiteimplícitamente todos los niveles previos de APIs. Las aplicaciones describen en el An-droidManifest los niveles mínimo y máximo de API en las que se pueden ejecutar, asícomo el nivel de la API preferida para la que están diseñadas.
Figura 2.2: Versiones de Android
2.2. Aplicaciones Android
Desde la API 21, cada aplicación de Android se ejecuta en su propio proceso de Linux.Este proceso se crea cuando parte del código de la aplicación necesita ejecutarse, y seguiráejecutándose hasta que ya no sea necesario o el sistema necesite memoria para que lautilicen otras aplicaciones.
Los desarrolladores de aplicaciones deben comprender las diferencias entre los compo-nentes de una aplicación (en particular, Activity, Service, y BroadcastReceiver) y su impactoen la vida del proceso de la aplicación. El hecho de no utilizar estos componentes correc-tamente puede provocar que el sistema mate los procesos de las aplicaciones mientrasrealizan una tarea importante.
Para comprender cómo funcionan las aplicaciones de Android, explicaremos brevemen-
te algunos conceptos clave del modelo asociado con ellos y sus componentes: Activity,
Service y Task; Intents, IntentFilters, BroadCastRecivers y PendingIntents; ContentProviders y
ContentResolvers; y AndroidManifest.
Activity: Las Activity son la parte visible de las aplicaciones. Esto significa que unActivity es la interfaz con la que el usuario interactúa. Además, es importante men-cionar que un Activity no es necesariamente un proceso, incluso las Activity y losService pueden compartir procesos. Además, una aplicación puede contener múl-tiples Activity. En este caso, cada Activity debe diseñarse teniendo en cuenta unaacción del usuario específica. Por ejemplo, una aplicación de agenda de contactospuede tener una Activity que muestre la información detallada de un contacto. Sinembargo, no es necesario que todas las Activity se definan en la misma aplicación:
15
una Activityd puede iniciar Activity que existen en otras aplicaciones del dispositi-vo mediante el uso de Intents.Por último, las Activity se pueden encontrar en diferentes estados durante su ejecu-ción. Estos estados junto con sus transiciones se presentan en la Figura 2.3.Para navegar por las transiciones entre los estados del ciclo de vida de la Activity, laclase Activity proporciona un conjunto central de seis llamadas a métodos: onCrea-te(), onStart(), onResume(), onPause(), onStop() y onDestroy(). El sistema invoca cadauna de estas llamadas cuando una Activity ingresa a un nuevo estado. Primero,cuando la Activity comienza, está en el estado starts. Durante esto se llama al méto-do OnCreate(). En este se deben definir las diferentes vistas y la información nece-saria para llevar a cabo la creación de la Activity. Luego, el siguiente método que seejecuta es OnStart(), que se encarga de poner la Activity visible para el usuario. Unavez que la Activity está visible, comienza a interactuar con el usuario ejecutando elmétodo OnResume(), llegando al estado starts. Finalmente, una vez que la Activityse está ejecutando se puede pausar cuando se debe ejecutar otra actividad. En esecaso la primera Activity ejecuta el método OnPause(), que debe cumplir sus respon-sabilidades rápidamente antes de que se produzca el cambio de Activity. Durantela ejecución de este método es necesario guardar la información del estado actualde la Activity pausada y detener las animaciones, entre otras funciones. Después depausar una Activity, el usuario puede reiniciarla volviendo a llamar implícitamenteal método OnResume() o el SO puede detener la Activity porque no ha estado visibledurante un largo período de tiempo. En el segundo caso, se ejecuta el método OnS-top(). Después de detener la actividad, a) se puede volver a hacer visible medianteel método OnRestart(), que a su vez llama al método OnStart() nuevamente, o b) sepuede destruir definitivamente mediante el método OnDestroy().
Service: Los Service son componentes de la aplicación que no tienen interfaz deusuario. Estos Service, a diferencia de las Activity, se pueden ejecutar en segundoplano. Como en el caso de las Activity, los Service tienen diferentes estados y transi-ciones, como se muestra en la Figura 2.4. Además, los estados de un Service varíande acuerdo con el método a través del cual fueron creados: startService() o bindSer-vice(). A continuación, se incluye un resumen de los estados en los que se puedeencontrar un Service. El primer caso de análisis es aquel en el que se ejecuta unservicio mediante una llamada al método startService(). Cuando se realiza esta lla-mada, el SO recupera el Service y, en el caso de que el servicio no se haya creadopreviamente, llama al método onCreate(). El siguiente paso es la llamada al méto-do onStartCommand(Intención,int,int). El Service continuará ejecutándose desde estemomento hasta que se llame al método Context.stopService() o stopSelf().Por otro lado, los desarrolladores pueden crear y obtener una conexión a un Ser-vice utilizando el método Context.bindService(). Si el Service no se creó previamente,este método lo crea llamando al método onCreate(), pero sin llamar al método onS-tart(). Luego, el cliente recibe un objeto IBinder que define una dependencia entrela aplicación y el Service. Esto permite al cliente hacer llamadas al Service a travésdel método onBind(Intent). Este Service continuará ejecutándose mientras la cone-xión continúe o se invoque el método onUnbind(). Finalmente, el Service se destruyemediante el método onDestroy().Finalmente, resaltamos que tanto Activity como Service no son sinónimos de proce-sos. De hecho, varios Service y Activity pueden compartir el mismo proceso..
16
Figura 2.3: Ciclo de vida de una Activity
17
Figura 2.4: Ciclo de vida de un Service
18
Task: Una tarea es una colección de actividades con las que los usuarios interactúancuando realizan un determinado trabajo. Las Activity se organizan en una pila en elorden en que se abre cada Activity. Por ejemplo, una aplicación de correo electró-nico puede tener una Activity para mostrar una lista de mensajes nuevos. Cuandoel usuario selecciona un mensaje, se abre una nueva Activity para ver ese mensaje,esta nueva Activity se agrega a la pila. En caso de que el usuario presione el bo-tón Back, esa nueva actividad finaliza y sale de la pila. Los usuarios deben tenerespecial cuidado con las tareas porque cuando tienen varias tareas ejecutándoseel sistema puede destruir algunas tareas para recuperar memoria por ejemplo. Enconsecuencia, el estado de las tareas que se destruyeron puede perderse.
Intent: Los Intent tienen por objetivo iniciar Activity, Service o BroadcastReceiversrealizando operaciones vinculantes en tiempo de ejecución. Cada Intent tiene unaestructura de datos donde se realiza una descripción abstracta de una operación.Por eso, la entrega de estos objetos se realiza de diferentes formas según el tipode componente que se active. En el caso de las Activity, el Intent se pasa a Con-text.startActivity() o Activity.startActivityForResult() para crear una Activity u obte-ner una Activity existente. Al resolver el Intent se puede hacer de manera explícitao implícita. En el caso de Intent explícito, el componente receptor se designa direc-tamente utilizando su nombre. Dado que los nombres de los componentes de otrasaplicaciones generalmente no son conocidos por los desarrolladores, estos tipos deIntent se utilizan principalmente en la comunicación interna de cada aplicación. Porotro lado, los Intent implícitos tienen el nombre del componente en blanco, ya queno se conoce. Este tipo de Intent generalmente se usa para activar componentes enotras aplicaciones. En este caso, es necesario que Android determine el mejor com-ponente para manejar el Intent implícito. Esto se hace comparando los contenidosde Intent con los de los IntentFilters, que son componentes asociados con aquellosque pueden resolver Intents.
IntentFilter: Activity, Service y BroadcastReceiver pueden tener uno o más IntentFil-ters para informar al sistema qué tipo de Intent pueden manejar. Cada IntentFilterdescribe las características del componente que recibir y manejar cierto tipo de In-tent. A través de estos IntentFilter, los Intent implícitos se pueden conectar con elcomponente correspondiente. Esta es la razón por la cual cada componente tieneun IntentFilter para cada trabajo que puede realizar. En la mayoría de los casos, losIntentFilter no están definidos en el código de Java, sino que están configurados enel AndroidManifest como elementos <intent-filter> porque Android debe conocer lascapacidades de los componentes antes de crearlos. La única excepción son los In-tentFilter utilizados por los BroadcastReceiver que pueden registrarse dinámicamentea través del método Context.registerReceiver().
BroadcastReceiver: Es un tipo de componente responsable de responder a los anun-cios de difusión. Estos anuncios pueden ser emitidos por el SO o por una aplicaciónen particular. En el primer caso se pueden encontrar anuncios como batería baja,mientras que el segundo caso podrían ser anuncios como aplicación o archivo des-cargado, utilizados para notificar a otras aplicaciones sobre algún elemento o datosque están disponibles para su uso.
PendingIntent: Es un contenedor de Intents que es responsable de compartir permi-
19
sos. Es decir que una aplicación puede otorgar permisos a otra aplicación a travésde estos objetos. Esto significa que una aplicación puede crear un PendingIntent paraotro componente y este último puede ejecutarlo como si fuera la aplicación original.
ContentProvider: Es el componente responsable de compartir datos persistentes através de aplicaciones proporcionando mecanismos para definir la seguridad de losdatos. Básicamente, un ContentProvider recibe una solicitud del cliente, la resuelvey devuelve los resultados. Un ContentProvider se identifica mediante una URI y susconsultas son similares a las consultas SQL. En particular, Android incluye Content-Providers que administran información como vídeo, audio, imágenes e informaciónde contactos
AndroidManifest: El archivo AndroidManifest.xml debe estar presente en todas lasaplicaciones de Android y contiene información esencial de la misma. Siguiendociertas pautas, este archivo especifica la asignación de procesos a las Activity y alos Service. Además, indica el paquete Java de la aplicación, describe los principa-les componentes de la aplicación, presenta sus capacidades y las clases que ejecuta,informa los permisos que necesita, declara los permisos que otras aplicaciones de-ben tener para interactuar con los componentes de la aplicación, indica la versiónde Android que el dispositivo necesita para ejecutar la aplicación y enumera lasbibliotecas requeridas por la aplicación.
Después de hacer una introducción a los componentes de las aplicaciones de Android,
presentaremos sus características generales. Las aplicaciones de Android están escritas
principalmente en Java porque es el lenguaje de alto nivel de Android. Sin embargo, es-
tas aplicaciones no se distribuyen como bytecode de Java, sino que se distribuyen como
bytecode especial. Para desarrollar aplicaciones los desarrolladores de Android deben
tener ciertos requisitos básicos de software como Java y AndroidStudio. En particular,
los desarrolladores deben tener el Kit de desarrollo de software de Android (SDK)2. En
particular, un SDK es un conjunto de herramientas de desarrollo de software que per-
mite la creación de aplicaciones particulares para un determinado paquete de software,
plataforma de software, hardware, sistema operativo, entre otros. En este caso, el An-
droid SDK proporciona las bibliotecas de la Interfaz de programación de aplicaciones y
las herramientas de desarrollo necesarias para crear, probar y depurar aplicaciones de
Android.
2.3. HPC en Smartphones
El área de computación de alto rendimiento (HPC -High Performance Computing-) escentral para la investigación de problemas complejos más allá de la informática, donde
2http://developer.android.com/sdk/index.html
20
los usuarios más comunes de HPC son investigadores científicos, ingenieros e institu-ciones académicas que necesitan un gran poder de cómputo. Para lograr el objetivo deproporcionar herramientas y soluciones a problemas complejos, HPC se basa en tecnolo-gías computacionales como clusters, supercomputadoras y cómputo paralelo. Además,la ejecución de HPC se puede llevar a cabo en entornos informáticos distribuidos talescomo Grids en los que los nodos deben ser capaces de ejecutar código computacionalintensivo para complementar/reemplazar supercomputadoras costosas y centralizadas.
Entonces, para introducir un dispositivo móvil en un entorno distribuido es necesario
demostrar que son capaces de ejecutar tareas intensivas. [Rodríguez et al., 2012b] mos-
tró que los smartphones son capaces de ejecutar código computacional intensivo incluso
cuando no fue diseñado para este tipo de dispositivo específicamente. En [Rodríguez
et al., 2012b] se usaron cinco benchmarks (PrimeBench, FFTBench, HanoiBench y Sieve-
Bench) para realizar las pruebas en cinco dispositivos diferentes (Dell Inspiron, Samsung
N150, ViewPad 10s, Nexus One y Samsung I5500). Las pruebas se ampliaron luego mi-
diendo el rendimiento de varios micro-benchmarks tales como la asignación de valores
de atributos y la creación de objetos, entre otros. En otras palabras, se comprobó empíri-
camente que los dispositivos móviles son adecuados para la ejecución del código HPC.
Específicamente, [Rodríguez et al., 2012b] muestra que los dispositivos móviles pueden
ejecutar una cantidad significativa de código intensivo antes de agotar su batería. En par-
ticular, en comparación con los dispositivos móviles contemporáneos de alta gama, como
notebooks o netbooks, un smartphone es capaz de ejecutar más operaciones computacio-
nales por unidad de batería. Por lo tanto, proponer buenas prácticas que permitan la
adaptación de códigos intensivos para optimizar el uso de los recursos limitados de los
dispositivos móviles podría reducir la brecha entre la ejecución en dispositivos tradicio-
nales y la ejecución en dispositivos móviles, así como también minimizar el consumo de
energía. Como nota al margen, cada propuesta para HPC es una propuesta interesante
para ser evaluada en aplicaciones de usuario final que tienen un uso elevado de CPU o
memoria.
Actualmente, trabajos como Pramanik et al. [2017] avalan esa hipótesis con las estadís-
ticas del potencial de computación de los smartphones. Los autores basaron su inves-
tigación en el hecho de que en un país como India muchas organizaciones no pueden
tener una supercomputadora. Los autores argumentan que el poder de computación de
los smartphones puede proporcionar la potencia informática equivalente a una super-
computadora moderna sin incurrir en altos costos.
2.4. Mobile Grids
De acuerdo con Foster and Iamnitchi [2003], un Grid es un sistema que coordina recursosdistribuidos y utiliza protocolos standard, abiertos y de uso general, y tiene interfacesque confieren una calidad de servicio no trivial. Este término nació debido a la existen-
21
cia de organizaciones que requerían una gran capacidad computacional para lograr susobjetivos pero que no podían obtener una supercomputadora. Como resultado, estas or-ganizaciones colaboraron compartiendo sus recursos de bajo costo y logrando un granpoder computacional equivalente o superior al de una supercomputadora.
Estos entornos distribuidos tienen características particulares. La primera característica
de un Grid es que los recursos están en diferentes lugares e interconectados a través de
una red, generalmente Internet. Por otro lado, la coordinación de estos recursos implica
que no existe una relación jerárquica. En consecuencia, dado que no debería haber un
control centralizado de los recursos, cada recurso podría basarse en diferentes SO. Por
lo tanto, los protocolos abiertos son necesarios para garantizar la interoperabilidad de
dichos sistemas.
La extensión de Grid Computing a dispositivos móviles ofrece una serie de ventajas Ro-
driguez et al. [2011b]. En primer lugar, los dispositivos móviles tienen una amplia gama
de sensores (micrófono, sensores de presión, etc.) que pueden compartirse. Estos sensores
permiten a los investigadores obtener y procesar datos de forma inmediata en situacio-
nes en las que antes era imposible realizarlos con dispositivos fijos. Como resultado, el
concepto de Grid puede llegar a lugares que eran inaccesibles como un área despoblada
(montaña, desierto). Este tipo emergente de sistemas Grid, que usan dispositivos móvi-
les, se conoce como Mobile Grid Li and Li [2010b].
Sin embargo, al extender el concepto de Grids a dispositivos móviles, el código fuente
de la aplicación debe adaptarse para su ejecución en este tipo de dispositivos con re-
cursos limitados. Particularmente, grandes secciones de código no pueden ejecutarse en
dispositivos móviles debido a su volatilidad y su autonomía energética. Entonces, es im-
portante lograr una refactorización correcta de las diferentes tareas que ejecutará el Grid
para obtener un uso óptimo de los recursos disponibles. En otras palabras, si las tareas
consumen grandes cantidades de energía, es posible que los dispositivos no terminen
una gran cantidad de ellas.
2.5. Green Computing
Green Computing es el uso ambientalmente responsable de las computadoras y los recur-
sos relacionados. Independientemente del entorno, la investigación de alto rendimiento
en informática se ha centrado tradicionalmente en la ejecución de tareas lo más rápido
posible. Sin embargo, toda esta investigación está siendo repensada para agregar eficien-
cia energética a la lista de factores críticos a considerar en el área de HPC, además del
rendimiento Basmadjian et al. [2015]. Se han llevado a cabo investigaciones que abarcan
la conocida pila de tres capas que comprende hardware (por ejemplo, adición de núcleos),
plataforma (por ejemplo, mejores planificadores de nivel de middleware) y aplicaciones
(por ejemplo, modelos de programación paralelos). De hecho, las estadísticas sobre el im-
22
pacto de la energía en los costos económicos en los Data Centers son impresionantes. Por
ejemplo, el consumo de energía representa el 15 por ciento de los gastos operacionales
totales Greenberg et al. [2008]. En 2007, la energía consumida en los centros de datos en
Europa Occidental fue de 56 TWh y aumentará a más de 100 TWh por año en 2020 Eu-
ropean Commission [2009]. Además de estas consecuencias, el manejo ineficiente de la
energía tiene consecuencias ecológicas negativas debido a las emisiones de CO2.
En respuesta, hay muchas propuestas Basmadjian et al. [2015] para aumentar la eficiencia
energética en los Data Centers. En el nivel del hardware, existen esfuerzos para mejorar
las CPU, los elementos de almacenamiento/red y la mecánica de los controladores de
refrigeración/calor. Dichas prácticas incluyen la implementación de CPU, servidores y
periféricos con uso eficiente de la energía, así como la reducción del consumo de recursos
y la eliminación adecuada de los desechos electrónicos (e-waste).
Con la creciente demanda de aplicaciones de software más complejas, las Tecnologías de
la Información y la Comunicación (TIC) han tenido un impacto negativo en el medioam-
biente debido a su creciente consumo de recursos y energía. El efecto de las TIC en el
desarrollo sostenible, especialmente en el software, es un tópico importante hoy en día
en Green Computing.
Recientemente se han realizado muchas investigaciones para obtener Green Software Ar-
dito and Morisio [2014], Pinto et al. [2015], Sahin et al. [2012], Dhaka and Singh [2016],
Hasan et al. [2016]. Algunos esfuerzos se centran en la creación de Green Software y
otros en la estructuración de procesos de diseño de software para ayudar a todos los in-
teresados en el desarrollo de Green Software. Otros enfoques se centran en la creación
de herramientas de software que miden el efecto del software en el medio ambiente y
el efecto de los entornos de desarrollo de aplicaciones en el software en términos de efi-
ciencia energética. Finalmente, hay trabajos que hacen hincapié en el SO para ayudar a
controlar el consumo de energía de las aplicaciones
2.6. Resumen
En este capítulo, proporcionamos la información básica necesaria para ayudar a los lecto-
res a tener una comprensión básica del área del problema de investigación y para promo-
ver la calidad general de nuestros análisis y conclusiones. Esta información proporciona
al lector el contexto esencial necesario para comprender el problema de investigación y
su importancia.
A lo largo de este capítulo presentamos el entorno en el que se presentará nuestro tra-
bajo. Todos los conceptos detallados (sistema operativo Android, aplicación Android,
HPC en smartphones, redes móviles y Green Computing) son necesarios para compren-
der el trabajo completo. Android es el SO seleccionado para ejecutar los experimentos
23
y, como consecuencia, necesitamos saber cómo desarrollar correctamente una aplicación
de Android. A medida que proponemos refactorizaciones para aplicaciones científicas,
mencionamos algunos trabajos que respaldan la hipótesis de que los dispositivos mó-
viles son dispositivos útiles para ejecutar aplicaciones HPC. Las dos últimas Secciones
(Sección 2.4 y Sección 2.5) presentan dos áreas importantes en las que nuestro trabajo
contribuirá colaborando para mejorar sus principales objetivos.
24
Capıtulo 3
Trabajos Relacionados
A lo largo de este capítulo, presentamos los trabajos relacionados que determinan el es-tado del arte en el área. En los últimos años, se han realizado esfuerzos para mejorar eldesarrollo de aplicaciones intensivas para aprovechar los recursos limitados y las nuevascapacidades de los dispositivos móviles. Una primera área relevante es Offloading. Offloa-ding es una técnica que promueve la transferencia dinámica de tareas intensivas de unaaplicación desde un dispositivo con recursos limitados a uno o más servidores que tienenmayor poder computacional, dando la ilusión de una gran potencia de computación enel dispositivo móvil. Esta técnica ahorra energía en los dispositivos móviles y logra unaejecución de código intensivo.
Desde entonces, la concepción tradicional sobre el valor de los dispositivos móviles ha
evolucionado para introducirlos como parte activa de las infraestructuras informáticas
intensivas. La experiencia ha demostrado que la ejecución de código intensivo en dis-
positivos móviles sin enviar el código a servidores externos es viable Rodriguez et al.
[2011b]. Por lo tanto, los recursos de los dispositivos móviles se ofrecen como recursos
para entornos informáticos distribuidos Rodriguez et al. [2011b], Murray et al. [2010].
Como resultado, en las siguientes Secciones describimos numerosos trabajos que han
centrado sus esfuerzos en la introducción de dispositivos móviles en infraestructuras
científicas, así como en el desarrollo de aplicaciones que aprovechan sus recursos limita-
dos. El resto de este Capítulo está organizado de la siguiente manera. En la Sección 3.1
se presentan y discuten trabajos relacionados con la técnica de Offloading. Después de
eso, la Sección 3.2 detalla las investigaciones cuyo objetivo principal es la introducción
de dispositivos móviles como proveedores de recursos en entornos computacionales dis-
tribuidos. En este tipo de entornos computacionales, el código fuente de las aplicaciones
debe optimizarse para consumir la menor cantidad de energía posible, ya que los dispo-
sitivos móviles dependen de su batería como suministro energético. Luego, la Sección 3.3
presenta trabajos que proponen técnicas para disminuir el consumo de energía modifi-
cando el código fuente de la aplicación. Finalmente, la Sección 3.4 presenta un resumen
25
de los trabajos analizados, los problemas abiertos y explica la relación de nuestro trabajo
con los trabajos presentados en este documento.
3.1. Offloading
La popularidad de los dispositivos móviles y la evolución de sus componentes de hard-ware ha llevado a los usuarios a esperar el mismo rendimiento de los dispositivos móvilesque de los dispositivos fijos. Sin embargo, los dispositivos móviles tienen recursos limita-dos que representan un desafío significativo para cumplir este objetivo. Por lo tanto, unasolución ampliamente utilizada en este contexto es una técnica llamada Offloading, queconsiste en delegar la ejecución de partes de una aplicación a otros dispositivos fijos [Sha-rifi et al., 2011]. Como resultado, esta técnica produce la ilusión de un procesamiento in-tensivo en el dispositivo junto con un mínimo consumo de energía. Básicamente, Offloa-ding reduce el consumo de energía en el dispositivo móvil y el tiempo de ejecución de lasaplicacioness mediante la delegación de la ejecución de la aplicación a entornos compu-tacionales como Clouds o servidores individuales en una modalidad cliente-servidor. Sinembargo, esta solución tiene algunas restricciones que afectan su usabilidad Kristensen[2010] (por ejemplo, los usuarios generalmente tienen que pagar por usar los serviciosde Clouds y los dispositivos móviles deben estar conectados a Internet). Luego, es ne-cesario analizar en qué situaciones aplicar Offloading es razonable. Esto significa que esimportante determinar cuándo Offloading podría ahorrar batería o reducir el tiempo deejecución sin aumentar excesivamente el uso de la red. En esta Sección presentamos tra-bajos relevantes que analizan cómo evaluar cuándo es conveniente aplicar Offloading. Enprimer lugar, la Tabla 3.1 resume los trabajos sobre Offloading utilizando 13 columnas,delas cuales se explican las columnas no triviales en los párrafos siguientes:
Táctica: Refiere a la táctica o criterio usado para evaluar cuando una tarea deberíaser ejecutada en un dispositivo externo.
Objetivo: Es el aspecto/cualidad que se desea optimizar.
Granularidad: Es una métrica de software que intenta cuantificar el tamaño de loscomponentes individuales que componen un sistema de software. Los componen-tes grandes (es decir, los que incluyen mucha funcionalidad) se denominan común-mente de granularidad gruesa, mientras que los componentes que proporcionanpoca funcionalidad se denominan generalmente de granularidad fina. Además, losOffloaders pueden trabajar con granularidades específicas.
Offloading restricicones: Son las características básicas que una tarea debe cumplirpara poder ser ejecutada en otro dispositivo. Si una tarea específica no cumple conestas características, no puede ser un candidata para ser enviada. Algunas de es-tas características se relacionan con el estado de la red (por ejemplo, un mínimo deancho de banda disponible es necesario o un máximo de latencia es tolerable), fide-lidad (por ejemplo, la fiabilidad del resultado debe estar por encima de un umbraldeterminado), tiempo de ejecución (por ejemplo, la tarea debe tener un mínimo detiempo de ejecución), etc.
26
Tipo de subrogados: Representa el tipo de subrogados que se utilizan para ejecutarlas tareas. Un subrogado es una entidad informática que se hace cargo del trabajocomputacional de alguna funcionalidad de una aplicación móvil. Un cliente es undispositivo que necesita algún software especial o características y configuraciónpara ser parte del sistema, mientras que una máquina virtual (VM) es una simula-ción de un sistema específico y se puede ejecutar en cualquier sistema. (Figura 3.1).
Tipo: Define el tipo de Offloader de acuerdo al momento en que se toman las deci-siones. Las decisiones se pueden tomar antes de la ejecución de la aplicación (está-ticas) o durante la ejecución de la aplicación (dinámicas).
Deployment de tareas: Indica la táctica utilizada para comunicar subrogados, ser-vidores y clientes.
Esfuerzo de desarrollo: Indica cuánto esfuerzo se necesita para usar el Offloaderen el software. Las categorías son: modificación de clases y métodos (alto), modi-ficación de la aplicación/clase principal pero no modificación de clases y métodosinternos (medio) o simplemente realizar alguna configuración sin modificar el có-digo de la aplicación (bajo).
Como se muestra en la Tabla 3.1 hay muchos factores que se deben considerar para de-terminar si es conveniente enviar una tarea a ser ejecutada en otro dispositivo. Primero,las tareas deben identificarse antes de enviarse. En particular, es necesario identificar quétareas están vinculadas a los recursos del dispositivo móvil local porque estas tareas no sepueden ejecutar en otro dispositivo. Por ejemplo, si una tarea utiliza el acelerómetro deldispositivo, sería imposible ejecutarla en otro dispositivo. Además, una evaluación de lasrelaciones de tarea podría ser necesaria. En total, el proceso de detección debe clasificarlas tareas en dos grupos principales: tareas descargables (aquellas que califican para serenviadas a otros dispositivos para su ejecución) y tareas no descargables (aquellas quesólo pueden ser ejecutadas en el dispositivo móvil).
Además, el Offloader debe evaluar si la ejecución remota de tareas descargables mejo-
ra la ejecución local. Una forma de evaluar si la descarga es beneficiosa es a través de
la evaluación del tiempo de ejecución de la tarea. Para esta evaluación es necesario te-
ner en cuenta el tiempo de ejecución (TE), la cantidad de código a transmitir (CT), el
número de bytes utilizados para recibir el resultado (DR), el ancho de banda de trans-
misión (TBW) y el ancho de banda de la red de recepción (BWR). Con esta información,
los desarrolladores pueden calcular el tiempo necesario para descargar el código con la
fórmula: To f f loading = CT/TBW + DR/BWR+ TE. Esta fórmula muestra que la descarga
es conveniente cuando el tiempo estimado de ejecución en el dispositivo móvil (MTE)
es mayor que To f f loading (MTE > To f f loading) Sharifi et al. [2011]. En un caso análogo, los
desarrolladores pueden usar el consumo de energía para determinar si realizan la des-
carga o no. Al igual que la evaluación del tiempo, la evaluación del consumo de energía
tiene una limitación: el consumo de energía de la aplicación varía según la plataforma
y los recursos utilizados [Flinn et al., 2002]. También, la evaluación consume recursos y,
como consecuencia, consume energía y necesita tiempo para ejecutarse. Como resultado,
27
Paper Año Táctica Objetivo GranularidadOffloading
restricciones
Tipo de
subro-
gado
TipoDeployment
de tareas
Esfuerzo de
desarrolloTest cases
Flinnet al.
[2002]2002
History-based
Latencia/Perfor-
mance/E-nergía
Fina Fidelidad Clientes Estática RPC Alto
Speechrecognition,
Latex documentpreparation
systemBalanet al.[2007,2002]
2002History-
based
Latencia/Perfor-mance
Fina Fidelidad/ Red Clientes EstáticaRPC/
wrapperMedio
Face Recognizer,Text to speech
Goyaland
Carter[2004]
2004 SiemprePerformance/
EnergíaGruesa
Seguridad/Fidelidad
VM Estática URL BajoSphinx SpeechRecognition,Data mining
Suand
Flinn[2005]
2005 Siempre Performance Gruesa Red VM EstáticaServidor y
Clientes Dinámica Proxy NingunoLinpack, Chessgame, 3D car
game
Cuadro 3.1: Resumen de Offloaders
28
el momento y la complejidad de la decisión es un tema de discusión e investigación en
esta área. Finalmente, en los párrafos siguientes discutimos una variedad de propuestas
relacionadas para implementar un Offloader para varios dispositivos móviles que usan
diferentes criterios para determinar qué tareas descargables deberían descargarse real-
mente.
Por último, las siguientes Subsecciones se dividen en dos áreas principales: enfoques
orientados al rendimiento y enfoques orientados a la energía. Esta clasificación es para
facilitar la comprensión de la gran cantidad de trabajos que se presentan en esta área.
Se eligió este orden para desarrollar las obras porque, cronológicamente, las primeras
investigaciones se centraron en mejorar el rendimiento de las aplicaciones. Además, los
enfoques de rendimiento son trabajos interesantes que podrían evaluarse para reducir el
consumo de energía en el dispositivo móvil.
3.1.1. Enfoques orientados a la performance
En este contexto, una de las primeras propuestas para manejar el Offloading es Spec-tra [Flinn et al., 2002]. Spectra se centra en la reducción de la latencia y el consumo deenergía, teniendo en cuenta la fidelidad, que se define como la fiabilidad de un resultadode la tarea (la fiabilidad de la respuesta del subrogado). Para medir el consumo de ener-gía y el tiempo de ejecución, Spectra calcula los recursos necesarios para ejecutar la tareaen un dispositivo. Esta estimación es una función basada en un perfil histórico de aplica-ciones, calculado utilizando un modelo de regresión lineal. Además, Spectra monitoreael comportamiento de la aplicación, modela el uso de recursos y predice las necesidadesfuturas de recursos. Por lo tanto, Spectra tiene monitores de recursos que miden la dis-ponibilidad de recursos locales y remotos, pero que a su vez consumen varios recursospara monitorizar y realizar los cálculos necesarios. La ecuación utilizada por Spectra paradecidir dónde se debe ejecutar la tarea se basa en la configuración del usuario. El usua-rio determina el peso de diferentes aspectos (tiempo, energía y fidelidad). Sin embargo,Spectra no está diseñado para admitir la ejecución paralela. Otra desventaja de este Of-floader es el hecho de que los comandos utilizados para la comunicación entre Spectra yla aplicación deben introducirse manualmente en el código de la aplicación.
Reducir el esfuerzo de los desarrolladores es una característica importante y deseablepara los Offloaders. En consecuencia, se propuso Chroma [Balan et al., 2007, 2002], quesubsume la funcionalidad de Spectra e intenta mejorarlo reduciendo el esfuerzo de losdesarrolladores. Para hacer esta mejora, Chroma proporciona una adaptación de códigosemiautomática. Además, en Spectra el soporte para monitorear recursos está fuera delcódigo de la aplicación, mientras que en Chroma está incluido en un conjunto de exten-siones del sistema operativo. Al igual que en Spectra, para decidir dónde ejecutar unatarea el usuario define una función de utilidad para cada tarea que describe el peso decada factor, como la velocidad y la energía de la CPU. Entonces Chroma intenta maximi-zar la tasa de fidelidad/latencia a través de la táctica seleccionada. Finalmente, Chromay Spectra tienen una desventaja ya que suponen que no es necesario enviar el código de
29
la aplicación porque la aplicación está instalada en los recursos de los subrogados queejecutan las tareas delegadas.
La siguiente etapa, que mejora el uso de subrogados, fue abordada por Goyal y Carter
en [Goyal and Carter, 2004] a través de un sistema basado en máquinas virtuales (VM),
como se muestra en la figura 3.1. La tecnología de VM permite utilizar el mismo subro-
gado para ejecutar diferentes aplicaciones desde diferentes dispositivos móviles y dis-
minuye el esfuerzo del desarrollador ya que no es necesario que modifique el código de
la aplicación. De manera similar, al igual que en los dos trabajos presentados anterior-
mente, el objetivo de Goyal y Carter es aumentar el rendimiento y reducir el consumo de
energía. Sin embargo, la sobrecarga de inicializar en el subrogado una máquina virtual
compatible con el sistema de Offloader en el subrogado es alta ya que la aplicación debe
descargarse de una URL específica. Como primer paso, el dispositivo móvil descubre to-
dos los subrogados posibles y, en un segundo paso, el dispositivo móvil envía una URL
y un script a los subrogados. Luego, los subrogados pueden descargar la aplicación de
la URL e instalarla en la VM utilizando la secuencia de comandos. 3.1 cuenta con un ser-
vidor de descubrimiento de servicios para conectar dispositivos móviles y subrogados.
Esto significa que cuando los dispositivos móviles usan el sistema, envían una solicitud al
servidor de descubrimiento de servicios y obtienen la dirección IP y el número de puerto.
El uso de VM aumenta la flexibilidad del sistema, y los subrogados no necesitan configu-
ración previa, evitando así el uso de un middleware específico. La principal desventaja
de este enfoque es que requiere que los dispositivos móviles estén conectados a Internet.
Otro sistema basado en VM es [Su and Flinn, 2005]. Como en Goyal y Carter, en Slings-hot se propone un sistema en el que el dispositivo móvil y los subrogados deben estarconectados a Internet, pero en Slingshot se presenta un nuevo componente, un servidor.Este servidor se usa para instalar la primera réplica de la aplicación, y luego de eso, lassegundas réplicas se instalan en los subrogados. Es importante mencionar un punto re-lacionado a considerar es que se necesita una red con baja latencia y conexión de anchode banda alto para usar este sistema con el fin de lograr aumentar el rendimiento de laaplicación, que es su objetivo principal. Dado esto, todas las tareas se ejecutan en más deun subrogado y los resultados se comparan en el servidor para verificar la confiabilidadde los mismos. Como nota al margen, si el servidor no está disponible, hay uno o másservidores auxiliares en la misma LAN. Finalmente, ninguno de los sistemas (Slingshot,y Goyal y Carter) tiene control sobre qué tareas deberían delegarse y cuándo. Entonces,una evolución de este tipo de sistemas reside en su capacidad para tomar decisiones entiempo de ejecución.
3.1.2. Enfoques orientados a energía
Aunque los trabajos descritos anteriormente representan un avance importante en Of-floading, ninguno de ellos tiene la reducción de consumo energético, que es el tema prin-cipal de esta tesis, como objetivo principal. Uno de los primeros sistemas cuyo objetivoprincipal es mejorar el consumo de energía y, además, minimizar el esfuerzo del desarro-llador se presentó en 2010 y se llama MAUI [Cuervo et al., 2010]. MAUI realiza Offloading
30
Figura 3.1: Cliente vs VM
de granularidad fina para aplicaciones OO, centrándose en aplicaciones de uso intensivode recursos. MAUI divide los métodos presentes en el grafo de la aplicación en localesy remotos para ejecutarlos utilizando programación reflectiva. Por lo tanto, MAUI hacedos versiones del código: una para la ejecución local en el dispositivo móvil y otra parala ejecución remota en el subrogado. Para delegar tareas, MAUI consta de tres módulos:una interfaz de decisión que reside en el servidor, un proxy que es responsable de contro-lar cada método candidato y un generador de perfiles que recopila información sobre laenergía consumida y otros datos. Para decidir qué tareas deben ejecutarse en los subro-gados, MAUI tiene un generador de perfiles que contiene información sobre la energíaconsumida por el CPU local por ciclo y sobre la latencia y el costo de energía del uso dela red para enviar y recibir las tareas. Finalmente, MAUI usa un mecanismo de tiempo deespera simple para evitar fallas en la ejecución de la aplicación.
En MAUI, se usa un sistema de perfiles único para evaluar dónde (smartphone o su-
brogado) se debe ejecutar una tarea; sin embargo, un nuevo sistema de doble perfil se
presenta en [Kristensen, 2010]. Este sistema se llama Scavenger y utiliza un sistema de
perfil individual y un perfil central para tomar decisiones sobre las diferentes ejecucio-
nes de tareas. Mientras que MAUI se centra en ahorrar energía, Scavenger se centra en
aumentar la potencia de la CPU y disminuir el tiempo de latencia de las aplicaciones, te-
niendo un mecanismo atractivo para evaluar en el área de consumo de energía también.
Por lo tanto, para disminuir el tiempo de latencia, el perfilador doble se basa en la estima-
ción del tiempo de ejecución según los tamaños de entrada y salida y la arquitectura de
la aplicación. Para hacer esta estimación, cada subrogado envía periódicamente su poder
31
de procesamiento disponible al dispositivo móvil. Sin embargo, los tiempos de ejecución
de diferentes tareas en cada arquitectura son diferentes y la potencia de procesamiento
de los subrogados debe calcularse de acuerdo con las tareas, lo que no se considera. Ade-
más, este generador de perfiles usa información adicional, como el ancho de banda y la
latencia de la red para estimar los tiempos de ejecución. Por otra parte, ni el factor de
estimación u otra información es predecible con lo que no es factible obtener una estima-
ción exacta. Otra innovación que introduce este sistema es la biblioteca de programación
que se debe incluir en la aplicación que los desarrolladores intentan modificar. Esta bi-
blioteca se puede importar automática o manualmente, de acuerdo con las preferencias
y el conocimiento de los desarrolladores, lo que reduce el esfuerzo a casi nada. Por otro
lado, los subrogados ejecutan un daemon para mantenerse conectados y para poder ins-
talar las aplicaciones a ejecutar. La última innovación en este sistema es un scheduler de
múltiples núcleos. Esto significa que las tareas y los perfiladores pueden aprovechar los
recursos de núcleos múltiples, una característica que falta en trabajos anteriores.
En la misma línea, se presenta un novedoso sistema basado en grafos Abebe and Ryan
[2012]. En este sistema, se usa un grafo que representa los recursos de los diferentes
subrogados para tomar decisiones para una ejecución eficiente y eficaz basada en una
heurística específica. No obstante, construir este grafo es una tarea compleja debido a la
complejidad de sus componentes. Los vértices modelan los componentes de la aplicación
(en la granularidad del nivel de clase), con el peso de un vértice como el uso de recursos
compuestos (memoria, energía, CPU, etc.) de todas las instancias del componente. Los
arcos representan el acoplamiento entre los vértices donde el peso de un arco se deter-
mina por la tasa de invocación y el costo de la misma. Entonces, un subrogado tiene que
ser responsable de construir el grafo. Como resultado, teniendo en cuenta los recursos y
el estado de la red, este sistema aumenta el rendimiento y disminuye el uso de recursos,
especialmente energía, en el dispositivo móvil.
En los últimos años, se describieron nuevos enfoques para reducir la energía. Por ejem-plo, AIOLOS [Verbelen et al., 2012] es un framework para Android presentado como uncomplemento para Eclipse. AIOLOS utiliza un modelo que tiene en cuenta los recursosdel servidor y el estado de la red para decidir en tiempo de ejecución si una tarea deberealizarse en un dispositivo móvil o enviarse a un subrogado. Delegar una tarea a unservidor subrogado es conveniente cuando el tiempo de ejecución remota es menor queel tiempo de ejecución local. Se mantiene un perfil basado en la historia para calcular eltiempo de ejecución local. Para estimar el tiempo de ejecución remota [Verbelen et al.,2012] introduce tres parámetros s, b y l, que representan la aceleración de CPU (una CPUde servidor es más rápida que la de un dispositivo móvil), ancho de banda de red y la-tencia de red respectivamente. Por último, la ecuación utilizada para estimar el tiempode ejecución remota es:
32
Tremote =1s ∑
iǫRM
(TCPU,locali)+
1b× (A + R)+ l + ∑
jǫCM
(TCPU,locali+
1b× (Aj + Rj)+ l) (3.1)
donde RM es la colección de tareas ejecutadas remotamente, CM define una colecciónde callbacks para manejar los resultados de tareas, A es el tamaño de la tarea delegada yR es el tamaño estimado de los datos de resultados devueltos.
Además, AIOLOS tiene en cuenta el uso de energía: una tarea debe descargarse si se aho-
rra energía mediante la ejecución remota (Esaved > 0). Finalmente, el potencial de ahorro
de energía se calcula con la siguiente ecuación:
Esaved = ECPUx ∑iǫRM
(TCPU,locali)−ETR × A−ERCV ×R− ∑
jǫCM
(ERCV × Aj +ETR ×Rj) (3.2)
En este caso, la decisión depende del modelo de energía del dispositivo móvil porqueECPU representa la energía consumida por unidad de tiempo por la CPU del dispositivomóvil. ETR y ERCV indican el costo de energía para transmitir y recibir un byte, respec-tivamente. No obstante, Verbelen et al. [2012] se centra en la optimización del tiempode ejecución porque estos parámetros de energía son difíciles de medir utilizando herra-mientas de software, mientras que los parámetros de tiempo se estiman a través de unperfil generado a partir de la historia de ejecución.
Mientras que los cuatro Offloaders previos proponen sistemas con componentes de de-cisión en tiempo de ejecución que incurren en gastos computacionales generales, Zhanget al. [2012b] describe DPartner, un sistema que permite preprocesar los códigos de apli-cación consumiendp menos recursos en el momento de ejecución. Básicamente, DPartnerenvía automáticamente las aplicaciones de Android modificando el bytecode de la apli-cación. Con este objetivo, Zhang et al. [2012b] divide el proceso de Offloading en cuatropasos. En primer lugar, con la ayuda de las anotaciones de código Java detecta qué tareasson movibles (descargables) clasificando como «ancladas» aquellas tareas que utilizanrecursos disponibles solo en el dispositivo móvil. En el segundo paso, las tareas movi-bles se refactorizan para poder descargarlas en los subrogados. En tercer lugar, el sistemadetecta qué tareas deberían descargarse. Para determinar qué tareas móviles se debenenviar a subrogados existen numerosas reglas y algoritmos. Como señalamos anterior-mente, tomar decisiones en tiempo de ejecución consume recursos; como consecuencia,los autores han estudiado algunos algoritmos de preprocesamiento estático para reducirlas decisiones de tiempo de ejecución. Finalmente, el último paso consiste en empaquetarla aplicación modificada en dos tipos de ejecutables (.jar y .apk).
Para determinar qué tareas deben descargarse, DPartner encuentra las principales n ta-reas intensivas para considerarlas para ejecutarlas en subrogados. Además, una instanciade tarea debe cumplir las siguientes dos fórmulas para ser adecuada para la descarga:
donde tphone es el tiempo de ejecución en el dispositivo móvil, to f f load es el tiempo deejecución en el servidor,dinput es el tamaño de los parámetros de entrada del método enbytes, doutput es el tamaño de los valores de retorno del método en bytes, r es la velocidadde transmisión de datos a través de la red, i = cpuserver/cpuphone es la relación de ciclode la CPU entre el servidor y el dispositivo móvil y E es el consumo de energía porunidad de tiempo de la aplicación. Ewi f iOr3G se calcula monitorizando los archivos deconfiguración de WiFi/3G, y EcpuO f f load se calcula utilizando el algoritmo de mapeo entrelas instrucciones bytecode y el consumo de energía propuesto en Binder [2006].
3.1.3. Resumen
Resumiendo, discutimos varios trabajos que representan los principales avances en elárea de Offloading. Hay algunos trabajos cuyo objetivo principal es mejorar el rendi-miento o la latencia, pero no el consumo de energía. Sin embargo, evaluar su impactoen el consumo de energía es interesante ya que, en general, el rendimiento y el consumode energía están relacionados Rodriguez et al. [2016a]. Disminuir el consumo de energíano es una tarea simple porque depende de la capacidad de recursos, características dered, valores de entrada y salida, etc. Aún así, mantener el uso de CPU, memoria y otrosrecursos bajos y disminuir el tiempo de ejecución es una buena táctica para reducir elconsumo de energía. Luego, utilizar los trabajos existentes para mejorar el consumo deenergía en los smartphones es una línea de investigación viable e interesante.
Después del análisis de trabajos representativos relacionados con Offloading, presenta-
mos algunos problemas comunes que surgen al tratar de reducir el costo de la ejecución
en dispositivos móviles mediante Offloading. En primer lugar, el esfuerzo de los desa-
rrolladores es una característica importante a tener en cuenta cuando se utilizan algunos
de estos enfoques. Sin embargo, incluso en el caso de los Offloaders que requieren poco
esfuerzo, la aplicación de cualquier técnica de Offloading no es una tarea trivial ya que
es necesario tener conocimientos previos sobre el Offloader que se está utilizando. En
segundo lugar, una buena estimación de los costos de las ejecuciones locales y remotas
para tomar la decisión es necesaria. Como se muestra, todos estos trabajos usan datos his-
tóricos para hacer predicciones. Entonces, las predicciones para las primeras ejecuciones
nunca son precisas. Además, esta información puede colapsar el sistema de almacena-
miento del dispositivo móvil debido a la gran cantidad de información que necesita el
Offloader. Una solución a este problema es usar un sistema de memoria caché distribui-
da [Sharifi et al., 2011]. En general, surge un nuevo problema cuando una tarea tiene una
amplia gama de variables de entrada y el modelo de estimación del Offloader no consi-
dera el efecto de introducir diferentes valores para estas variables [Sharifi et al., 2011].
34
3.2. Schedulers distribuidos para dispositivos móviles basados
en energía
Basado en la premisa de que los smartphones y otros dispositivos móviles son capacesde ejecutar código computacionalmente intensivo Rodríguez et al. [2012b], a continua-ción discutimos trabajos que consideran los dispositivos móviles para la ejecución decódigo intensivo en entornos distribuidos híbridos. A diferencia de Offloading, estos tra-bajos promueven la ejecución de código intensivo en dispositivos móviles. Sin embargo,en ambos casos, el objetivo principal es reducir el consumo de energía o el tiempo deejecución en el dispositivo móvil.
El comienzo de entornos distribuidos híbridos que unen recursos computacionales des-
de dispositivos móviles y servidores fijos, particularmente Gtids móviles, fue en 2003. No
obstante, uno de los primeros trabajos que demuestra la utilidad de los dispositivos mó-
viles para la ejecución de aplicaciones HPC utilizando entornos distribuidos es Huynh
et al. [2011], que a su vez motivó una mayor investigación. Los autores de Huynh et al.
[2011] proponen un modelo de computación híbrida para ejecutar secciones de código
paralelas semi-intensivas de aplicaciones en dispositivos móviles, incluidos los disposi-
tivos móviles como nodos activos. Usando este algoritmo paralelo, los autores desarro-
llaron dos soluciones: offline y online. En la solución offline, el algoritmo se ejecuta por
completo en una supercomputadora. Por otro lado, la solución online permite ejecutar el
mismo algoritmo complejo en varios dispositivos móviles, como smartphones o tabletss.
Como conclusión, los autores infieren que independientemente del hardware diferen-
te con capacidades muy diferentes, el resultado final es en cierto sentido agnóstico del
hardware: la predicción de la versión online es indistinguible del cálculo paralelo de la
supercomputadora. Finalmente, los autores afirman que han logrado ”supercomputación
en un smartphone”.
A pesar de que se han llevado a cabo investigaciones exhaustivas sobre plataformas dis-
tribuidas, la producción de aplicaciones de uso general para las plataformas distribuidas
que incluyen estos nuevos dispositivos móviles es un problema que no ha sido claramen-
te reconocido hasta hace poco tiempo Rodriguez et al. [2011b]. A pesar de los resultados
importantes con respecto a los métodos de paralelización Mateos et al. [2008, 2010a,b,
2011a] y las técnicas para facilitar la movilidad del software han surgido en el pasado
cercano Mateos et al. [2010c], Crasso et al. [2011], Fernando et al. [2013], Furthmuller and
Waldhorst [2012], Mateos et al. [2010a], estos avances se limitan a las infraestructuras pa-
ralelas y distribuidas tradicionales, que dependen de servidores fijos conectados a una
red con intervalos de tiempo predecibles y estables. Como resultado, han surgido dife-
rentes puntos de vista sobre la integración de dispositivos móviles en las infraestructuras
de Grid Computing que explotan estos avances anteriores. Por ejemplo, Rodriguez et al.
[2011b], Loke et al. [2015] se centran en las redes de procesamiento con uso intensivo de
CPU que integran dispositivos móviles como smartphones y tablets.
35
Al principio, los dispositivos móviles estaban conectados a Grids solo funcionando como
interfaces para administrar y supervisar recursos, pero en los últimos años, los disposi-
tivos móviles se han integrado para funcionar como nodos activos de Grids Fernando
et al. [2013]. Desde esta integración, se han propuesto varios métodos para hacer una in-
tegración adecuada, centrada principalmente en la programación de tareas. Por lo tanto,
la mayoría de estos nuevos schedulers se basan en la modificación de algunos paráme-
tros en schedulers existentes, en lugar de un scheduler nuevo y óptimo para dispositivos
móviles Rodriguez et al. [2010].
El primer ejemplo de estas adaptaciones se presentó en min Park et al. [2003], en el que
se propone un scheduler basado en la premisa de que los dispositivos móviles a menudo
se desconectan de la red. Básicamente, este scheduler envía una tarea al nodo con más
probabilidad de estar conectado cuando la tarea se completa. Esta probabilidad la cal-
cula según un modelo de Poisson. Sin embargo, una limitación de este trabajo es que el
scheduler necesita saber de antemano el tiempo de ejecución de cada tarea, lo que no
siempre es posible, e involucra un proceso de Poisson que necesita una gran cantidad de
procesamiento de CPU para ser computado. Además, min Park et al. [2003] presenta una
simulación para determinar la cantidad óptima de nodos móviles según la cantidad de
tareas y el tiempo de CPU necesarios.
Diferente del enfoque descrito en min Park et al. [2003], donde el scheduling es dinámico,
Shivle et al. [2006] analiza numerosos algoritmos de scheduling estática cuyo objetivo es
minimizar la energía consumida por las aplicaciones que se basan en la comunicación de
subtareas, es decir, tareas con dependencias. Las limitaciones de este estudio son que al-
gunos parámetros (por ejemplo, energía consumida dentro de una unidad de tiempo por
un dispositivo o cuántas unidades de tiempo son necesarias para completar una tarea)
se deben conocer de antemano y la asignación se realiza de forma estática (es decir, no
considera la posibilidad de que los dispositivos fallen antes de finalizar el procesamiento
de una tarea). Sin embargo, este trabajo compara seis heurísticas diferentes utilizando
diferentes parámetros y obtiene resultados interesantes, incluso cuando estas heurísticas
consumen menos CPU que el cálculo del proceso de Poisson. Para concluir, los autores
declaran que se puede seleccionar una heurística específica en función de las caracterís-
ticas del dominio de la aplicación.
En Ghosh and das [2010] las limitaciones del trabajo previo se abordan considerandotareas homogéneas independientes (los mismos requisitos de CPU, RAM y red). En estetrabajo, el scheduler negocia el pago con cada nodo para ejecutar tareas pendientes yrealizar una asignación de costos óptima. Un modelo de fijación de precios económicosrige los beneficios de costos de los propietarios de dispositivos móviles para permitir quese lleven a cabo tareas computacionales complejas en esos dispositivos. Luego, el objetivode los autores es diseñar un esquema de asignación de tareas costo-óptimo basado en unaestrategia de precios justos para Grids móviles que soporte la movilidad del nodo. Paraesta negociación, los autores simularon los resultados de la aplicación de tres algoritmos
36
diferentes con una complejidad de O(n) basado en la teoría de juegos. Este algoritmotiene dos limitaciones. Primero, las tareas rara vez consumen exactamente los mismosrecursos, y segundo, los pagos para cada tarea deben negociarse, lo que genera un tiempode ejecución adicional. Entonces, el objetivo de este algoritmo es minimizar los costossobre la maximización del uso de recursos limitados que se derivan en un scheduler queno toma en cuenta el consumo de energía u otros recursos limitados como memoria oCPU de dispositivos móviles. En consecuencia, una tarea puede agotar una batería móvilsin finalizar su ejecución o puede consumir varios recursos (por ejemplo, CPU o RAM),alterando otros usos del dispositivo móvil.
Por otro lado, Li and Li [2010a] propone un modelo en el que la utilidad del Grid es la
variable para maximizar sin exceder la capacidad de recursos, destacando la batería. Este
modelo presta especial atención al uso de la energía de las baterías, ya que es el recurso
el que determina la capacidad de la red: cuando la batería se agota, el dispositivo ya no
se puede usar. El principal inconveniente del modelo es su alto costo computacional, ya
que utiliza multiplicadores de Lagrange para calcular el costo de energía, el precio de la
capacidad de recursos informáticos y el precio de la capacidad de recursos de la red. Sin
embargo, el propósito de los autores es dividir el problema en dos subproblemas utili-
zando dos tipos diferentes de componentes -agentes- para resolverlos. En primer lugar,
los agentes de recursos de Grid representan los intereses económicos de los proveedores
de recursos; y, segundo, un agente de aplicación que contiene los intereses de la aplica-
ción de usuario Grid que utiliza el Grid para lograr su objetivo teniendo en cuenta una
función de utilidad descrita para cada dimensión de QoS (recursos y energía necesarios,
tiempo máximo, pago máximo, entre otros). Después de definir los agentes, el modelo
funciona en iteraciones, cada iteración consta de tres pasos:
1. Los agentes de recursos de Grid actualizan su ubicación
2. Los agentes de recursos actualizan su precio individual
3. Se publica una descripción del recurso en el mercado delvGrid para negociar con
los agentes de la aplicación
Como puede verse, este modelo tiene un problema compartido por varios trabajos: ne-
cesita conocer los parámetros, como la capacidad de energía y la capacidad de cálculo,
de antemano. En consecuencia, este modelo se evaluó utilizando una simulación de una
topología con múltiples LAN interconectadas en las que se consideraron y variaron los
estados de carga de la batería, la red y el sistema. Los resultados se midieron utilizan-
do diferentes parámetros como el porcentaje de energía consumida, el porcentaje de los
recursos totales utilizados, la eficiencia de asignación y el número de tareas cuyas restric-
ciones de plazos no superan el número total de tareas.
No obstante, los esfuerzos previos en el área, las fórmulas complejas que todos estosschedulers necesitan calcular, hacen que la planificación de tareas sea una actividad que
37
consume mucho tiempo y recursos. Como consecuencia, se presenta un algoritmo sim-ple de programación de tareas para dispositivos móviles llamado Simple Energy-AwareScheduling (SEAS) enRodriguez et al. [2010]. El algoritmo SEAS intenta estimar un buenuso de los recursos, especialmente la batería, teniendo en cuenta los estados previos yactuales de los dispositivos móviles. SEAS estima el tiempo de batería restante conside-rando la descarga como una constante y actualiza el tiempo restante de acuerdo con losestados anterior y actual. La principal ventaja de este algoritmo es que puede calcularseen tiempo real, es ligero en recursos computacionales y no requiere conocimientos pre-vios sobre parámetros inciertos, como cuánta energía consume un dispositivo por unidadde tiempo de ejecución, o cuántas unidades de tiempo de ejecución son necesarios paracompletar una tarea. Sin embargo, SEAS no considera las demandas computacionales dela tarea cuando asigna tareas a los dispositivos. Como consecuencia, SEAS puede enviaruna tarea a un dispositivo que no tiene la capacidad de terminarla.
En un trabajo posterior, los autores de Rodriguez et al. [2010] desarrollaron diferentesschedulers para Grids móviles basadas en técnicas de robo de tareas. El robo de tareasocurre cuando un nodo del Grid está inactivo y toma tareas de otros nodos para mante-nerse ocupado, tratando de equilibrar la carga en el Grid. Las técnicas de robo de tareasevaluadas en [Rodriguez et al., 2014] tienen en cuenta el consumo de energía, las capaci-dades computacionales y el estado de la batería como en Rodriguez et al. [2010]. Cuandose asigna una tarea a un dispositivo móvil, la tarea se pone en cola hasta que el dispositivomóvil pueda ejecutarla. A pesar de esta simple asignación, la tasa de consumo de energíavaría de acuerdo con varios factores, como la carga de trabajo y el uso de la red. Además,los sensores de batería de los dispositivos móviles no son muy precisos. Como resultado,la elección del scheduler puede no ser la mejor, pero la replanificación no es compatible.Por otro lado, los algoritmos de robo de tareas son una opción viable cuando un disposi-tivo finaliza todas sus tareas asignadas mientras que otros tienen tareas en sus colas. Losalgoritmos de robo de tareas permiten que los dispositivos tomen tareas para ejecutardesde otro dispositivo. Los algoritmos de robo aleatorio tradicionales consisten en elegirun dispositivo móvil aleatorio para robar, o víctima, y funcionan bien en muchos esce-narios y su costo computacional es muy bajo Van Nieuwpoort et al. [2010]. Teniendo encuenta la simplicidad, que es parte de la premisa de SEAS, Rodriguez et al. [2014] compa-ra una estrategia que considera el estado de la batería y el consumo de energía para elegira la víctima con los algoritmos tradicionales de robo aleatorio. En consecuencia, Rodri-guez et al. [2014] muestra que un scheduler de robo de tareas consciente de la energíaes más eficiente para las redes móviles que los algoritmos de robo aleatorio tradicionalesporque aumenta notablemente el número de tareas que se pueden ejecutar utilizando lamisma cantidad de energía.
Un nuevo entorno computacional híbrido apareció en 2013, proponiendo integrar dispo-sitivos móviles como recursos, llamado Mobile Cloud Computing Fernando et al. [2013].Como mencionan los autores, la integración de dispositivos móviles en este paradigmaes inminente porque representan una gran cantidad de poder de cálculo no utilizado.Como resultado, no solo se necesitan buenos schedulers de tareas sino también mode-los de desarrollo con conciencia energética para dispositivos móviles, de modo que loscódigos de tareas utilicen los recursos móviles con prudencia. En esta sección se presen-taron muchos esfuerzos centrados en schedulers conscientes de la energía que incluyendispositivos móviles como "ciudadanos de primera clase" en entornos distribuidos. Enparticular, ninguno de ellos evalúa el impacto dentro de la tarea o dentro de la aplicación.
38
La siguiente subsección se refiere a la eficiencia energética del código de aplicación, pre-sentando una línea de investigación complementaria que pretende refactorizar códigospara dispositivos móviles, independientemente de la técnica de planificación de tareas,es decir, del scheduler de trabajos móviles.
3.3. Modelos de desarrollo de software y metodologias basados
en energía
En los últimos años, se han realizado diferentes esfuerzos para aumentar la eficiencia
energética en los Data Centers al procesar aplicaciones de uso intensivo de recursos. En
esta área hay varios enfoques que disminuyen el consumo de energía en diferentes ni-
veles, como hardware, sistema operativo o código fuente de alto nivel (es decir, nivel de
aplicación). Mencionaremos algunos trabajos de cada nivel prestando especial atención a
los trabajos de código fuente de alto nivel, ya que nuestro objetivo principal es reducir el
consumo de energía a través de la refactorización de códigos.
Para analizar el consumo de energía en todos los niveles es necesario saber qué recursos
consumen más energía. Según Minas and Ellison [2009] la mayor cantidad de energía
consumida se produce por la pantalla, seguida del CPU y la memoria. Utilizando este
conocimiento, los científicos pueden proponer diferentes enfoques para desarrollar mo-
delos y directrices en cualquier nivel. Por ejemplo, Chen et al. [2012] presenta una herra-
mienta perfilado a1 nivel de proceso y un módulo de energía de sistema que elimina la
energía desperdiciada por las aplicaciones por su comportamiento anormal para el cual
la información de hardware es esencial. Como conclusión, Chen et al. [2012] afirma que
los investigadores deberían diseñar modelos de energía simples con buena capacidad de
respuesta para obtener mediciones reales e instantáneas para controlar el consumo de
energía.
Otros científicos analizan el consumo de energía de la fabricación y el uso del hardware
junto con el consumo en la ejecución de software Ardito and Morisio [2014]. Con respec-
to a la fabricación y el uso del hardware, la fase más costosa en términos de consumo de
energía es el diseño y la fabricación (54% del consumo total de energía), seguido del uso
(15%). Para la fase de uso, Ardito and Morisio [2014] presenta pautas para la eficiencia
energética en cuatro niveles diferentes: infraestructura, aplicación, sistema operativo y
hardware. En las directrices de nivel de aplicación incluye diseño eficiente de UI, utiliza-
ción de programación basada en eventos cuando sea posible, utilización de programación
de bajo nivel, reducción la redundancia de datos y utilización de herramientas de perfil
de energía.
Además, de acuerdo con Pinto et al. (2015) hay una gran variedad de trabajos que abor-
39
dan el problema del consumo de energía a nivel de aplicación y se pueden clasificar en
diferentes grupos. Las dos áreas principales en las que el consumo de energía es un te-
ma novedoso son la programación móvil y paralela. Las investigaciones de aplicaciones
móviles se centran en 6 cuestiones para reducir el consumo de energía: interfaz de usua-
rio, descarga de CPU, solicitud de HTTP, piratería de software, aplicación en ejecución
continua y operaciones de E / S. Por otro lado, en la programación paralela hay 3 fac-
tores principales: cadenas de copias excesivas, paralelismo de abrazo y programación de
GPU. Aunque Pinto et al. (2015) examina varios documentos presentados en las conferen-
cias de ingeniería de software más destacadas, los autores no analizan trabajos basados
en computadoras personales o servidores, esta última es nuestra plataforma de destino
secundaria para nuestras refactorizaciones con conciencia energética. Además, a diferen-
cia de Ardito y Morisio (2014); Pinto et al. (2015), estamos especialmente interesados en
estudiar primitivas de programación que no sean generales sino que sean concretas y
conscientes de la energía, ya que nuestro trabajo apunta a mejorar el consumo de energía
a través de refactorizaciones de códigos fuente impulsadas por primitivas comunes en
códigos HPC.
Además, de acuerdo con Pinto et al. [2015] hay una gran variedad de trabajos que abor-
dan el problema del consumo de energía a nivel de aplicación y se pueden clasificar en
diferentes grupos. Las dos áreas principales en las que el consumo de energía es un tópico
novedoso son la programación móvil y la programación paralela. Las investigaciones de
aplicaciones móviles se centran en 6 cuestiones para reducir el consumo de energía: inter-
faz de usuario, carga de CPU, solicitud HTTP, piratería de software, ejecución continua
de una aplicación y operaciones de E/S. Por otro lado, en la programación paralela hay
3 factores principales: copias de datos excesivas, paralelismo y programación de GPU.
Aunque Pinto et al. [2015] examina varios documentos presentados en las conferencias
de ingeniería de software más destacadas, los autores no analizan trabajos basados en
computadoras personales o servidores, los cuales son nuestra plataforma de experimen-
tación secundaria. Además, a diferencia de Ardito and Morisio [2014], Pinto et al. [2015],
nosotros estamos especialmente interesados en estudiar micro-benchmarks concretos y
basados en ahorro de energía, ya que nuestro trabajo apunta a mejorar el consumo de
energía a través de refactorizaciones de códigos fuente.
3.3.1. Dispositivos móviles
Los servidores y los centros de datos no son el único objetivo al reducir el consumo deenergía. Los dispositivos móviles dependen de su batería como fuente de energía; enton-ces, ahorrar energía es una preocupación importante cuando se desarrollan aplicacionesmóviles. No solo la motivación es extender la duración de la batería y, por lo tanto, au-mentar la experiencia del usuario móvil, sino también soportar cómputos complejos endispositivos móviles a la luz de paradigmas computacionales más nuevos Fernando et al.[2013]. Como consecuencia, hay varios trabajos cuyo objetivo principal es minimizar el
40
consumo de energía en las aplicaciones moviles y estos son los trabajos en los que estamosmás interesados. Las secciones anteriores describen las diferentes funciones de los dispo-sitivos móviles en entornos distribuidos, pero cómo desarrollar código para dispositivosmóviles es otro campo de relevancia en el área. En los siguientes párrafos, discutiremoslos trabajos relacionados con el consumo de energía de la programación de aplicacionesmóviles, la mayoría de ellos centrados en dispositivos móviles Android debido a la po-pularidad del sistema operativo Android. Es importante mencionar que algunos trabajosen esta área se centran en diversas características para mejorar el tiempo de ejecución yel consumo de energía o la calidad del software. Estamos especialmente interesados enel consumo de energía y el tiempo de ejecución, ya que es el objetivo principal de estatesis. La performance está estrechamente relacionada con el consumo de energía porquereducir el tiempo de ejecución sin cambiar la cantidad de procesamiento y el uso de lamemoria por unidad de tiempo equivale a reducir el consumo de energía.
Como un hecho interesante, aunque el resultado esperado es que el Código nativo tengaun mejor rendimiento que el código escrito en lenguajes de alto nivel como Java, losresultados reales muestran que el tiempo de ejecución depende del tipo de operación. Porejemplo, Cheng-Min et al. [2011] compara el código Java con el código nativo de Androiden términos de tiempo de ejecución utilizando 12 benchmarks populares divididos en lassiguientes 8 categorías:
Cálculo numérico con recursión: los benchmarks de Ackermann y Fibonacci eva-lúan el tiempo de ejecución de realizar llamadas a funciones recursivas y tambiénacumulan velocidad de administración de memoria.
Facilidades de biblioteca: Hash y Hash2 prueban el tiempo de ejecución de la im-
plementación de hashMaps en bibliotecas. En Java, se utiliza la biblioteca estándar
que provee la clase Hash Map, mientras que en C++ se utiliza el gcc no estandar
hash_map.
Estructura de datos creada por el usuario: las pruebas Heapsort y Matrix no depen-
den de una biblioteca sino que implementan estructuras de datos personalizadas y
prueban el tiempo de ejecución de sus operaciones.
Polimorfismo: esta prueba utiliza los benchmarks Methcall y Objinst para ver cuán-
to tiempo lleva hacer una llamada en un momento determinado.
Bucles anidados: esta prueba consta de seis bucles anidados, cada uno de los cuales
ejecuta N rondas.
Generación aleatoria de números: esta prueba usa cálculos numéricos puros con
solo algunas variables y sin estructuras de datos.
Tamiz de Eratóstenes: este es un algoritmo simple para encontrar números primos
de manera eficiente. Se usa una matriz de valores booleanos, donde cada elemento
representa si su valor de índice puede ser primo o no.
41
Cálculos con enteros Asignación de memoria
Número deentradas
100 300 500 800 1,000 100 300 500 800 1,000
Dalvik 15 172 561 1,453 2,338 114 150 311 538 647
Native C 5 63 197 510 827 11 33 54 83 109
Mejora 66% 63% 64% 64% 64% 90% 78% 82% 84% 83%
Cuadro 3.2: Evaluación (ms) Sangchul and Wook [2010]
Operaciones de cadena: la prueba strcat concatena un string al final de otro string.
Como resultado, los autores demuestran que Native Code es más rápido que el códigode Java en un promedio de 34.2%, tomando valores entre 99.98% y -158.39%. Si bien enalgunos casos particulares el código Java es mejor, en la mayoría de los casos, el Códi-go nativo supera a Java. En particular, Java supera a Native Code en Hash (-158.39%),Heapsort (-26.61%) y Random (-47.72%) benchmarks.
Otro trabajo similar analiza qué tipo de algoritmos son los que presentan mayores me-
joras en el tiempo de ejecución usando Native Code. Para determinar cuándo el Código
nativo proporciona un mejor rendimiento que los lenguajes de alto nivel, Sangchul and
Wook [2010] clasifica los algoritmos en cinco áreas: retardo de comunicación, operacio-
nes con enteros, operaciones de coma flotante, acceso a memoria y asignación de heap.
Para evaluar cada área, Sangchul and Wook [2010] desarrolla aplicaciones de Android
usando la biblioteca de códigos nativos usando C y una aplicación de Android usando el
mismo algoritmo desarrollado en Java y ejecutándose en la máquina virtual Dalvik. Los
autores muestran que los retrasos en la comunicación que se producen debido al uso de
la interfaz Java no tienen influencia en los resultados experimentales. Por otro lado, el
cálculo de enteros, el cálculo de coma flotante, el algoritmo de acceso a la memoria y la
asignación del heap logran resultados más rápidos utilizando la biblioteca C nativa que
utilizando el mismo algoritmo escrito en Java. Sin embargo, los algoritmos de acceso a
memoria no disminuyen su tiempo de ejecución cuando el número de parámetros de en-
trada aumenta cuando se utiliza C. Luego, a medida que aumenta el número de entrada,
la mejora obtenida usando C nativo aumenta también. En otras palabras, la diferencia de
tiempo de ejecución entre Dalvik y C nativo es proporcional en operaciones como cálcu-
los enteros, mientras que esa proporción cambia considerablemente para los algoritmos
de asignación de memoria cuando aumenta el número de entrada, como se muestra en la
Tabla 3.2.
En conclusión, aunque el código nativo fue más eficiente en todas las pruebas, el trabajorecomienda usar bibliotecas C nativas cuando la aplicación requiere accesos frecuentes ala memoria o realiza cálculos complejos.
42
A pesar de que Native C mejora el tiempo de ejecución en comparación con Java, es-
te último es un lenguaje muy popular para desarrollar aplicaciones de Android, ya que
proporciona portabilidad, seguridad, robustez y simplicidad Barisone et al. [2001]. De
hecho, Java admite programación OO, multithreading y computación distribuida imple-
mentada a nivel de lenguaje, independencia de plataforma, administración automática
de memoria y manejo de excepciones, lo que la hace interesante para aplicaciones de uso
general Barisone et al. [2001]. Además, varios estudios muestran que Java es un lenguaje
útil para desarrollar aplicaciones de HPC Taboada et al. [2011].
Sabiendo que Java es un lenguaje eficiente y viable para implementar HPC, podemos
evaluar diferentes propuestas para ahorrar energía utilizando este lenguaje. Comenzan-
do, Google propone sus propias prácticas de codificación Java para mejorar el tiempo
de ejecución de la aplicación Android1. Es importante mencionar que cuando se mantie-
ne el consumo de CPU y memoria por unidad de tiempo pero se reduce el tiempo de
ejecución, el consumo de energía también disminuye. La lista de estas prácticas incluye
algunas conocidas para mejorar el tiempo de ejecución: evitar crear objetos innecesarios,
preferir el uso estático sobre virtual, uso de constantes, evitar getters/setters internos,
usar la sintaxis mejorada de bucles, considerar paquetes en lugar de acceso privado con
clases internas privadas, evitar el uso de coma flotante, conocer y utilizar las bibliotecas,
y usar los métodos nativos cuidadosamente. En los siguientes párrafos, se explican estas
prácticas y se presentan algunos trabajos que las evalúan:
Evitar crear objetos innecesarios: la creación de objetos no es barata porque, a pesarde la existencia de un Garbage Collector que abarata la asignación, asignar memo-ria siempre es más costoso que no hacerlo. Además, cuando se asigna memoria esnecesaria una recolección periódica para liberar espacio de objetos no utilizados, loque también empeora el tiempo de ejecución de la aplicación. Por lo tanto, los desa-rrolladores deben evitar la creación de instancias de objetos que no sean necesarios.
Preferir el uso estático sobre virtual: si no necesita acceder a los campos de un objeto
se debe establecer el método como estático. Las invocaciones serán entre un 15%
y un 20% más rápidas, ya que las invocaciones estáticas no requieren una tabla
indirecta para alcanzar el método
Usar constantes: Considerar la declaración en la parte superior de una clase presen-tada en el Algoritmo 3.1.En este algoritmo, el compilador genera un método de inicialización de clase, lla-mado <clinit>, que se ejecuta cuando la clase se utiliza por primera vez. El métodoalmacena el valor 42 en intVal, y extrae una referencia de la tabla de constantes parastrVal. A partir de ese momento el código que hace referencia a intVal usará el valor
entero 42 directamente, y los accesos a strVal usarán una instrucción relativamenteeconómica. Sin embargo, es importante mencionar que esta optimización se aplicasolo a tipos primitivos y constantes de String.
Evitar Getters/Setters internos: una práctica común en OO es usar getters para ac-ceder a los valores de los atributos en lugar de acceder directamente a los campos.Sin embargo, las llamadas a métodos son costosas. Es razonable seguir prácticascomunes de programación OO y tener getters/setters en interfaces públicas perodentro de una clase los desarrolladores deben acceder directamente a los valores.
Usar la sintaxis mejorada para bucles: el bucle for forzado (for-each loop) se puede
usar para colecciones que implementan la interfaz Iterable de Java y para matrices.
Con las colecciones, se asigna un iterador para hacer las llamadas de interfaz a los
métodos hasNext() y next(). En cambio, con un ArrayList, un bucle contado escrito
a mano es aproximadamente tres veces más rápido. Al iterar usando las variables
de índice o iteradores se presentan oportunidades para errores de programación. El
bucle for-each evita la posibilidad de este error al ocultar el iterador o la variable de
índice además del compilador y las optimizaciones JIT que se obtienen con un bucle
for-each. Además, un bucle for-each evita el uso de estas variables adicionales, lo
que introduce un procesamiento adicional y afecta el tiempo de ejecución.
Considerar el uso de paquetes en lugar del acceso privado con clases internas: con-siderando la definición de clase privada presentada en el Algoritmo 3.2, se defineuna clase privada y la cual puede acceder directamente al campo definido en laclase externa. El problema reside en que para permitir que una clase interna accedaa miembros privados de una clase externa el compilador Java genera algunos mé-todos sintéticos que deben ser llamados por la clase privada y dar como resultadouna disminución de rendimiento "invisible". Los desarrolladores pueden evitar lasobrecarga al declarar que los campos y métodos a los que se accede tienen accesoal paquete.
Evitar utilizar Floating-Point: el punto flotante es dos veces más lento que los inte-ger en dispositivos Android. Sin embargo, en hardware moderno no hay diferenciaen términos de velocidad entre los tipos float y double, pero el double es dos vecesmás grande.
Conocer y usar las bibliotecas: la mayoría de los idiomas proporcionan bibliote-
cas integradas o funcionalidad incorporada cuyo objetivo principal es exponer las
funciones comunes para su reutilización. Los ejemplos son la funcionalidad pa-
ra buscar y clasificar estructuras de datos o algoritmos de generación de números
44
1: public class Foo {2: private class Inner {3: void stuff() {4: Foo.this.doStuff(Foo.this.mValue); {} }5: private int mValue;6: public void run () {7: Inner in = new Inner(); mValue = 27; in.stuff(); }8: private void doStuff(int value) {9: System.out.println("Value is - value); }
10: }
Algorithm 3.2: Acceso privado
aleatorios. Usar este soporte tiene ventajas significativas sobre el uso de implemen-
taciones ad-hoc. Al usar una funcionalidad incorporada, los desarrolladores apro-
vechan el conocimiento de los expertos que lo escribieron y la experiencia de quie-
nes lo usaron antes que ellos. Una segunda ventaja es que los desarrolladores no
tienen que perder tiempo escribiendo funcionalidades comunes. Además, el rendi-
miento de dicho soporte tiende a mejorarse con el tiempo. En particular, muchas de
las funcionalidades integradas de la plataforma Java se han reescrito a lo largo de
los años, lo que resulta en mejoras dramáticas en el tiempo de ejecución Bloch Bloch
[2001].
Usar los métodos nativos cuidadosamente: Desarrollar código nativo de Androidutilizando el NDK de Android no es necesariamente más eficiente que la progra-mación con el lenguaje Java. Hay un costo asociado con la transición Java-códigonativo. Además, el compilador JIT (Just In Time, que convierte activamente el códi-go de la aplicación en una forma que se ejecuta más rápido) no puede optimizar através de estos límites. También, el código debe compilarse para cada arquitecturaen la que se ejecutará.
Algunos trabajos científicos han verificado estas buenas prácticas y evaluado su impactoen el tiempo de ejecución y en el consumo de energía. Uno de estos trabajos es Toniniet al. [2012], que evalúa la mejora de evitar el uso de métodos getter y setter, y el usode la sintaxis apropiada para un loop. Además, Tonini et al. [2012] evalur el impacto deestas prácticas en una aplicación real. Los resultados muestran que evitar el uso de gettery setter es 2.9 veces más rápido que usarlos, y el uso de la sintaxis for-each adecuadaes 1.25 veces más rápido que no hacerlo. Finalmente, la aplicación real modificada es1.33 veces más rápida que la aplicación original. De acuerdo con Tonini et al. [2012] estoshallazgos serán ampliados por los autores para evaluar explícitamente la efectividad deestas prácticas.
Mientras que los trabajos anteriores se centran en la evaluación del tiempo de ejecución,
los párrafos siguientes discuten trabajos cuyo objetivo principal es optimizar el consumo
de energía en los dispositivos móviles. En esta área Gottschalk et al. [2012] propone detec-
45
tar y eliminar el código que consume excesiva energía mediante técnicas de reingeniería
de software. Gottschalk et al. [2012] analiza la estructura del código móvil para encon-
trar patrones de consumo de energía (malas prácticas), llamados olores codificados. El
olor a código de término se ha presentado y utilizado para el tiempo de ejecución en los
años 90, y se ha presentado y lo estudia exhaustivamente utilizando un catálogo de Code
Smells. Según Fowler [1999]: "un Code Smell es una indicación de superficial que generalmente
corresponde a un problema más profundo en el sistema". Otra forma de ver los Code Smells
es con respecto a los principios y la calidad del sistema Suryanarayana et al. [2015]: "los
Code Sells son ciertas estructuras en el código que indican la violación de los principios
de diseño fundamentales y afectan negativamente a la calidad del diseño". Finalmente,
Gottschalk et al. [2012] utiliza el mismo término pero para evaluar el consumo de ener-
gía. Luego, los autores presentan un método de detección y reestructuración para 7 Code
Smells:loop bug, dead code, in-line method, moving too much data, immortality bug,
redundant storage of data y using expensive resources que se describen en los párrafos
siguientes:
Loop bug: Se produce un error de ciclo cuando un ciclo se ejecuta indefinidamen-te en el background debido a causas externas, por ejemplo un servidor al que es-tá vinculada la aplicación se ha bloqueado. Como resultado, la aplicación intentacontactar al servidor consumiendo energía por la conexión. Como primer paso, esnecesario detectar los ciclos que vuelven al estado inicial del sistema. Después, paraevitar el error de cilclo, los desarrolladores pueden introducir un número máximode iteraciones para cada ciclo.
Dead code: Es código fuente que nunca se usa pero necesita cargarse en la memoriay, por lo tanto, consume energía. Algunos códigos muertos se pueden detectar yeliminar como una optimización de nivel de compilador. Algunos códigos muertosestán presentes en métodos que nunca se llaman. Este Code Smell de energía puededetectarse mediante la localización de métodos que nunca se llaman, métodos quese invocan bajo condiciones que nunca surgen. En este último caso, se debe realizarun análisis de código más detallado. Finalmente, si se detecta código muerto debedescartarse.
In-line method: Reemplazar una llamada de método con el cuerpo del método lla-mado puede ahorrar energía. In-line method es el opuesto a extracción de méto-do Fowler [1999] definido como una técnica para reducir el código duplicado yaumentar la capacidad de mantenimiento del código. Entonces, la aplicación de es-ta refactorización puede, por lo tanto, disminuir el mantenimiento y la legibilidaddel código. Para detectar llamadas a métodos que pueden afectar el consumo deenergía, es necesario realizar un análisis dinámico (es decir, realizar un perfil de laaplicación en ejecución y registrar la frecuencia con la que se produce cada llamadade método y refactorizar estableciendo un umbral del número de invocaciones).
Moving too much data: El movimiento de datos representa la comunicación entreel procesador y la memoria. Si varias partes de las aplicaciones o diferentes aplica-
46
ciones acceden al mismo conjunto de datos, generalmente se llama y se almacenavarias veces la misma información. Incluso si dos memorias separadas necesitanlos mismos datos que se calcularon antes la mejor solución es usar cachés de nivelsuperior. Cuando se desarrolla una aplicación, algunas veces los diferentes méto-dos necesitan datos que hayan sido guardados previamente por otro método (porejemplo, al consultar los métodos de lectura y escritura correspondientes). Los desa-rrolladores pueden reducir el consumo de energía usando una táctica similar a losaplicados para In-line method: los métodos que solo leen datos tienen que ser re-emplazados por el método que calcula los datos que se recuperarán (el uso de CPUconsume menos energía que el acceso a la memoria Barroso and Holzle [2007]).
Immortality bug: Describe la reaparición de una aplicación después de que el usua-rio la cerrara explícitamente. Una aplicación podría crear otra instancia de sí mismaal recibir la señal de cierre del sistema operativo, o bien, otra aplicación la monitoreay la reinicia inmediatamente después de su cierre (p. Ej., MediaServer2 o Google-Maps3). La detección de este comportamiento no es una tarea fácil, pero se puederesolver utilizando un número persistente de reinicios. Este número se compara conun número que indica los reinicios máximos consecutivos después de los cuales setermina el "ciclo de reinicio"
Redundant storage of data: Esta es la situación en la que diferentes métodos al-macenan los mismos datos en la memoria en lugar de compartirlos. Entonces, esnecesario identificar los métodos de almacenamiento de datos y compararlos paraencontrar aquellos que almacenan los mismos datos. Después de esta detección, sepueden combinar los métodos que almacenan los mismos datos.
Using expensive resources: Los desarrolladores deben tener en cuenta las diferen-tes alternativas para utilizar los recursos más baratos disponibles, por ejemplo losdatos de posicionamiento global mediante WiFi consume menos energía que el usodel GPS para el mismo objetivo. Entonces, los desarrolladores deben conocer el con-sumo de cada alternativa diferente. Si se encuentra un recurso costoso de energíase debe verificar si sería posible reemplazarlo por otro.
Finalmente, Gottschalk et al. [2012] demuestra que la detección de Code Smells es via-ble en la práctica utilizando GReQL (lenguaje de consulta de grafos) para mapear Co-de Smells a consultas de grafos Kullbach et al. [1999]. Particularmente, Gottschalk et al.[2012] representa el código fuente usando TGraphs Ebert et al. [2008] que son grafos diri-gidos con nodos y vértices tipados, valorados y ordenados. Los TGraph se acompañan detecnologías basadas en metamodelos para definir, manipular, analizar, consultar, visuali-zar y transformar grafos. Por otro lado, GReQL es un lenguaje de expresión declarativapara analizar TGraphs, que se puede aplicar a diversos servicios de ingeniería inversa,por ejemplo cálculo de referencias cruzadas, métricas de software, división de progra-mas, etc. Sin embargo, aún se requiere una mayor validación de las técnicas presentadasy una estimación del posible ahorro de energía para mostrar las ventajas y limitacionesdel enfoque. Esto significa que los beneficios de refactorizaciones específicas deben de-mostrarse en trabajos futuros.
2https://code.google.com/p/android/issues/detail?id=67653goo.gl/5RAzSmcontent_copyCopy short URL
47
En líneas similares, en Thiagarajan et al. [2012] se presenta un análisis del consumo deenergía producido por la navegación web. A pesar del hecho de que Thiagarajan et al.[2012] no se trata de HPC para dispositivos Android, evalúa el consumo de energía paraactividades comunes en aplicaciones móviles lo cual es interesante para nuestro trabajo.Específicamente, evalúa la energía utilizada por un navegador móvil para cargar pági-nas web utilizando páginas web populares como Amazon o Facebook, con y sin utilizarel caché del navegador. Entonces, Thiagarajan et al. [2012] estudia en detalle el consu-mo de energía de cada tipo de elemento cargado en una página web: JavaScript, CCS eimágenes. Además, analiza los beneficios de utilizar Offloading para representar páginasweb en dispositivos móviles. Los resultados indican que la creación de un contenido encaché del sitio web no evita el tráfico de red, ya que hay contenido dinámico que no sepuede almacenar en caché. Sin embargo, el consumo de energía es mayor cuando no serealizó el almacenamiento en caché. Teniendo en cuenta los elementos individuales, losresultados muestran que renderizar imágenes toma una fracción significativa de la ener-gía total de renderizado, JavaScript consume más energía cuando los archivos Javascriptson grandes y complejos, el costo de energía de los archivos CSS depende de la cantidadde elementos de estilo utilizados. Luego, para reducir la cantidad de consumo de ener-gía Thiagarajan et al. [2012] propone pautas para el desarrollo web móvil. Estas buenasprácticas incluyen:
Reducir el consumo de energía de JavaScript: reducir los JavaScripts en una páginamóvil para contener solo las funciones utilizadas por la página.
Reducir el consumo de energía de CSS: reemplazar varios archivos CSS con solo un
archivo CSS que contenga solo las reglas requeridas por la página puede reducir
significativamente la energía consumida (por ejemplo, la página de Apple redujo
su consumo de energía en un 40% con esta refactorización).
Consumo de energía de las imágenes: el formato JPEG es el formato con mayor
eficiencia en el consumo de energía para todos los tamaños de imagen probados
(este formato consume entre un 20% y un 30% menos de energía).
Como mencionamos anteriormente, Thiagarajan et al. [2012] evalúa el uso de la técnicade Ofloading para reducir el consumo de energía de renderizar páginas web en dispo-sitivos móviles. Al usar un proxy front-end que cambia el tamaño de las imágenes paraadaptarse a la pantalla del teléfono se puede reducir el consumo de energía, especialmen-te en sitios que no tienen una versión móvil. A pesar de estas mejoras espectaculares, estatáctica tiene algunas limitaciones: en primer lugar, los usuarios pierden la capacidad deacercar rápidamente las imágenes (con este enfoque, un acercamiento requiere descargarla parte ampliada de las imágenes). En segundo lugar, el contenido enviado cifrado me-diante SSL no puede ser reducido por el proxy. Por otro lado, el uso de un servidor deback-end para la descarga no es viable debido a la energía necesaria para transmitir orecibir datos a través de las radios (WiFi o 3G).
Este conocimiento se puede complementar con la evaluación del costo de envío, recep-ción y recolección de información a través de la red WiFi Li and Halfond [2014]. La prin-
48
cipal conclusión de Li and Halfond [2014] es que a pesar de asignar memoria no es gratisy los desarrolladores deben evitar asignar memoria, recolectar datos y transferir gran-des mensajes (1,000 bytes) es beneficioso en términos de uso de energía. Luego, a partirde estos trabajos, los desarrolladores proporcionan una guía de buenas prácticas paradesarrollar páginas web y sus contenidos.
En este contexto ADEL (Automatic Detector of Energy Leaks) Zhang et al. [2012a] presen-ta un software para detectar fugas de energía de comunicaciones de red innecesarias. Seproduce una pérdida de energía cuando las aplicaciones usan energía para realizar tareasinútiles. Los autores mejoraron el consumo de energía de seis aplicaciones en un 57% ydetectaron cuatro causas comunes de pérdidas de energía:
Interpretación errónea de la semántica de API en la devolución de llamada: unaaplicación que crea un subproceso de descarga separado puede no matar el sub-proceso y puede seguir descargando después de que la aplicación finalice.
Comportamiento de actualización de datos ineficaz: un widget que actualiza su
estado ya sea que la pantalla esté activa o no.
Descargas repetitivas: una aplicación que no almacena en caché el contenido que se
necesita varias veces.
Precarga anticipada agresiva: un esquema de captación previa realmente agresivo
que no mejora la experiencia del usuario.
Estos dos trabajos muestran que el uso correcto de los recursos puede disminuir el con-sumo de energía en una aplicación. Entonces, tener conocimiento sobre los recursos y lasdiferentes tácticas para usarlos es crucial para los desarrolladores móviles. Según Höpf-ner and Bunse [2010], es posible rediseñar un sistema de software en el que los recursosde hardware disponibles se utilizan de forma eficiente en energía, reemplazando recur-sos que consumen demasiada energía por uno o más recursos que optimizan el uso deenergía en aplicaciones locales y distribuida. Höpfner and Bunse [2010] analiza posiblessustituciones en torno a tres recursos:
CPU - Comunicación: una alta carga de CPU puede ser reemplazada por transferen-cia de datos y comunicación. Los cálculos con uso intensivo de la CPU se puedenenviar a un servidor o distribuirse entre varias computadoras. Además, uno puedereducir la transmisión de datos mediante la compresión, que, sin embargo, requiereun uso adicional de la CPU. La compresión de los datos a transmitir a veces requieremás energía que la transmisión de datos sin comprimir, ya que comprimir la infor-mación implica un costo de energía para la compresión y la descompresión. Por lotanto, es importante considerar la información sobre el contexto de la implementa-ción. Las refactorizaciones se pueden aplicar utilizando el patrón de estrategia bienconocido, lo que permite a la aplicación decidir dinámicamente si se usa compre-sión o no.
49
CPU - Memoria: la sustitución de la carga de la CPU por acceso a la memoria seconoce como la materialización de las vistas en el área de los sistemas de bases dedatos. Por lo general, representa la decisión de almacenar resultados temporales.
Memoria - Comunicación: las réplicas y los sistemas de caché pueden reducir la can-
tidad de comunicación. Sin embargo, la replicación completa solo reduce la eficacia
de la comunicación, mientras que las cachés de almacenamiento dependen de la ca-
pacidad de reutilizar los datos en caché. Los datos disponibles en un dispositivo no
deben transmitirse, pero los datos redundantes pueden estar desactualizados, por
lo que se requieren mecanismos de sincronización para comunicarse con el servidor
y recibir dichas actualizaciones.
Como conclusión, Höpfner and Bunse [2010] afirma que el uso de la CPU requiere menosenergía que el uso de memoria (primaria y secundaria), mientras que la comunicación dered requiere más energía que las otras dos.
Un trabajo muy interesante es Li and Gallagher [2016] que propone un framework para
optimizar el consumo de energía en aplicaciones móviles. El framework propone una ba-
se para la optimización de código mediante herramientas automáticas, siendo el primero
que logra esto para un lenguaje de alto nivel como Java. En un estudio de caso la eva-
luación experimental muestra un ahorro del 6,4% a l50,2% del consumo de energía de
la CPU. Este framework utiliza las siguientes estrategias de refactorización de códigos:
desdoblado de ciclos, desencadenamiento de ciclos, combinación de If, In-Line method,
eliminación de sub-expresiones comunes, propagación constantes, extracción de código
invariante en ciclo, eliminación de variables de inducción y reemplazo por función de
biblioteca.
Como mencionamos anteriormente, las aplicaciones móviles actuales requieren recursosde hardware y conectividad de red lo que aumenta el consumo de energía. Las técnicasde diseño de software para el ahorro de energía no solo se pueden aplicar al CPU, a lamemoria y al uso de la red, sino también a la evaluación de reasignación de métodosinternos y la descarga de métodos. Corral et al. [2015] evalúa dos técnicas de diseño desoftware diferentes: reasignación de método, que se refiere a la ubicación de fragmentosde código en diferentes ámbitos de ejecución dentro de un único objetivo (por ejemplo,nivel de kernel, nivel de aplicación, nivel compartido de biblioteca) y descarga de méto-do, que hace referencia a la ubicación de tareas en recursos externos. Aunque este trabajoevalúa el uso de Offloading como una forma de reducir el consumo de energía, su ob-jetivo es analizar la reasignación de métodos y la refactorización de aplicaciones paraaprovechar este análisis. Usando este análisis, se recomienda una reorganización de lasclases y métodos a través de los diferentes niveles de la pila de software. Finalmente,utilizando estos ámbitos, los autores evalúan los siguientes cinco benchmarks:
N-body: Realiza muchas simulaciones que requieren patrones de acceso a memoriapresentes en muchas operaciones como representaciones de imágenes.
50
Fasta: Genera y escribe secuencias aleatorias de ADN en una estructura de matriz.
Por lo tanto, presenta diferentes instrucciones en la administración de arreglos.
Chameneo-redux: Solicita encuentro simétrico de thread por lo que ejerce caracte-
rísticas importantes sobre el uso de threads.
Árboles binarios: asigna y desasigna árboles binarios ejerciendo la gestión de las
estructuras de datos.
Fannkuch-redux: accede a través de índices a una secuencia de enteros y genera
diferentes permutaciones. Luego, evalúa las operaciones altamente vinculadas a
E/S y el uso de CPU.
Para evaluar estos benchmarks en los diferentes ambientes los autores varían el valorde la entrada de datos N. Al analizar todas las combinaciones, concluyen que la energíaconsumida por Native Code tiende a ser similar a la del código de Java para valores pe-queños de N. Sin embargo, C siempre es más eficiente que Java para cualquier valor deN. Esto indica que la eficiencia energética en la utilización de recursos es mejor cuandolos métodos se ejecutan directamente en el shell del sistema operativo. En cuanto a Of-floading de métodos, concluyen que solo funciona mejor si los datos involucrados en laejecución son altos. Como conclusión, dependiendo de las necesidades computacionalespuede ser recomendable reasignar o enviar un método para ahorrar energía (hasta el 90%de la energía ahorrada).
Finalmente, otro recurso ampliamente utilizado para ejecutar aplicaciones en dispositi-vos móviles es utilizando técnicas de threading. Sin embargo, existen diferentes alternati-vas para desarrollar aplicaciones de múltiples threads y estas alternativas consumen dife-rentes cantidades de energía. Luego, en Pinto et al. [2014] los autores evalúan el consumode energía de diferentes alternativas de construcciones de gestión de threads y evalúan larelación entre el número de threads, las estrategias de división de tareas, el volumen dedatos y el consumo de energía. Para evaluar los diferentes aspectos, los autores utilizanvarios benchmarks conocidos:
Knucleotide: Benchmark de uso intensivo de memoria sin puntos de sincroniza-ción.
Maldebrot: Benchmark intensivo de CPU sin puntos de sincronización.
Spectralnorm: Benchmark de uso intensivo de CPU que sincroniza los threads uti-
lizando una barrera.
Imagenes más grande: Benchmark intensivo de E/S que tiene dos puntos de sin-
cronización.
N-queens: Benchmark intensivo de CPU sin puntos de sincronización.
51
Sunflow: rendering de imágenes.
Xalan: Benchmark de procesamiento de documentos.
H2: Benchmark de modelo de transacciones bancarias.
Una de las principales conclusiones es que el consumo de energía aumenta a medida que
aumenta el número de subprocesos, y luego disminuye gradualmente a medida que el
número de subprocesos se aproxima al número de núcleos de CPU, dibujando una cur-
va Λ. Además, en la mayoría de los benchmarks que usan técnicas de subprocesamiento
deberían mejorar el tiempo de ejecución, pero, como mencionamos anteriormente, el con-
sumo de energía aumenta a medida que aumenta el número de subprocesos. Entonces,
en este contexto más rápido no implica más verde. Los autores también evalúan tres esti-
los de programación diferentes para aplicaciones de múltiples threads: ForkJoin, Thread
y Executor. Concluyen que para aplicaciones intensivas de E/S, el tipo Thread tiene el
mejor consumo de energía, mientras que el ForkJoin tiene el peor consumo de energía.
Con respecto a la división de tareas, los hallazgos revelan que para ForkJoin las cargas de
trabajo asimétricas en aplicaciones centradas en datos son más amigables con la energía
que las cargas de trabajo simétricas. Además, se evaluó el ancho de forking y los autores
determinaron que un ancho de forking excesivo puede aumentar el consumo de energía.
Es importante mencionar que los experimentos asociados a la división de tareas no se
evaluaron para otros estilos porque sus patrones de programación no caen naturalmente
en estos estilos de división de tareas. Finalmente, la última contribución de ese trabajo
indica que el tamaño de los datos tiene un papel importante en el consumo de energía.
Como primera conclusión, determinaron que la relación entre el tamaño de los datos y el
consumo de energía sigue una curva convexa (mayor tamaño de datos, más consumo de
energía por unidad de datos).
Como conclusión, la Tabla 3.3 resume los trabajos detallados en esta sección. Las colum-nas de la Tabla son:
Nivel: indica en qué nivel se aplican las refactorizaciones (nivel de aplicación, nivelde hardware o nivel del sistema operativo).
Objetivo: detalla qué característica se evalúa en cada trabajo. Los trabajos presenta-
dos en esta sección evalúan el consumo de energía (batería) o el tiempo de ejecución
(performance).
Enfoque: muestra qué enfoque se define en el trabajo.
Casos de estudio: es el número de estudios de casos a través de los cuales se evalúa
el enfoque.
52
Paper Nivel Objetivo Operación
Casosde es-
tudioMejora Evaluación
Cheng-Minet al. [2011]
Aplicación PerformanceComparas Native code y
Java12 -158% - 99.98% Benchmarking
Sangchuland Wook
[2010]Aplciación/Hardware Performance
Comparas Native code yJava
5 63% - 90%Comunicación/
Cálculo/Memoria
Tonini et al.[2012]
Aplicación PerformanceEvalua la misma
funcionalidad con códigodiferente
3 22% - 65%Google’s
guidelines
Gottschalket al. [2012]
Aplicación BateriaDetecta y refactoriza Code
Smalls7 - Code smells
Thiagarajanet al. [2012]
Aplicación BateriaEvalua operaciones
comunes en web browsers3 20% - 30% Web browsers
Li andHalfond
[2014]Hardware Bateria
Evalua el tamaño óptimode los mensajes enviados
por la red1 -
Comunicacióny memoria
Zhang et al.[2012a]
Aplicación BateriaDetecta lagunas de
consumo de energía4 up to 57% Comunicación
Corral et al.[2015]
Hardware BateriaCompara Java code,
Native Code y regular C5 up to 90% Benchmarking
Pinto et al.[2014]
Aplicación/Hardware BateriaEvalua diferentes técnicas
de administración dethreads
8 -Técnicas deThreading
Höpfnerand Bunse
[2010]Sistema Operativo Bateria
Propone estrategias dereemplazo de recursos
3 - Uso de recursos
Cuadro 3.3: Resumen de guías
53
Mejora: muestra el porcentaje de mejora en el consumo de energía. Es importante
destacar que algunos autores no han informado los resultados exactos de sus enfo-
ques, que es una limitación importante en esta área.
Evaluación: indica el área de software/hardware cubierta por cada trabajo.
Podemos afirmar que estos trabajos contribuyen a producir guias de desarrollo o a detec-tar buenas prácticas para desarrollar aplicaciones móviles de buena calidad para apro-vechar los recursos de los dispositivos móviles. Como podemos ver, estos trabajos sepueden combinar para desarrollar diferentes tipos de aplicaciones móviles. En esta área,varios trabajos se centran en Java porque su popularidad y porque es un lenguaje conmuchas características interesantes para el software móvil, incluyendo portabilidad, se-guridad, robustez y simplicidad. Aunque el uso del código nativo es más eficiente enalgunos casos, existen numerosos desarrollos en Java para dispositivos móviles y mu-chos desarrolladores calificados en este lenguaje. De hecho, las estadísticas basadas en elrepositorio de aplicaciones de Google Play muestran que el 52.98% de las aplicaciones deAndroid disponibles, el 88.76% de las principales aplicaciones de Android y el 75.62% delas nuevas aplicaciones de Android usan la biblioteca de soporte de Android4, que estádesarrollada en Java. Sin embargo, una de las limitaciones de este catálogo de trabajoscientíficos es que el impacto real de aplicar estas prácticas en aplicaciones reales no siem-pre se evalúa. Luego, es necesario evaluar este impacto junto con el equilibrio entre elesfuerzo del desarrollador y el beneficio de su aplicación, teniendo en cuenta al mismotiempo los criterios de calidad tradicionales, como la reutilización y la modificabilidaddel código.
3.3.2. Servidores y computadoras personales
Estamos especialmente interesados en el nivel de código fuente de alto nivel ya que nues-tro enfoque apunta a mejorar el consumo de energía a través de la refactorización de có-digo. En esta línea, Sahin et al. [2012] comienza la evaluación en el desarrollo de alto nivelya que evalúa el consumo de energía de los patrones de diseño en servidores. En Sahinet al. [2012], los autores crearon una nueva herramienta para medir el consumo de ener-gía de una aplicación en ejecución y para generar el mapeo entre el uso de energía y lospatrones de diseño. Para mapear patrones de diseño y consumo de energía los autoresseleccionaron 15 patrones de diseño, 5 en cada una de las tres categorías: creacional, es-tructural y conductual. Utilizando estos patrones de diseño, los autores concluyeron queel uso de patrones de diseño puede aumentar y disminuir la cantidad de energía consu-mida. Sin embargo, los patrones de diseño dentro de una categoría no afectan el uso deenergía de manera similar, y los impactos en el uso de energía no pueden ser estimadosartefactos de este nivel.
Con respecto al diseño detallado de la aplicación, Dhaka and Singh [2016] estudia hasta
qué punto la corrección de un diseño incorrecto afecta el consumo de energía en función
de Code Smells. La investigación muestra que las permutaciones de eliminación de Code
Smells producen diferentes niveles de consumo de energía para las versiones de softwa-
re resultantes. Dhaka and Singh [2016] analiza el impacto sobre el consumo de energía
de la eliminación de tres de los Code Smells más comunes (God Class, Feature Envy y
Brain Method), individualmente y secuencialmente. Los resultados muestran tendencias
uniformes de energía en todas las aplicaciones cuando se crean versiones refactorizadas
eliminando estos Code Smells. También se observa que las versiones refactorizadas gene-
radas aplicando God Class, Feature Envy y Brain Method generan un consumo mínimo
de energía en comparación con las generadas al aplicar otras secuencias. Debemos des-
tacar que el código correcto genera una nueva versión que consume más energía que la
versión original. Esto significa que Dhaka and Singh [2016] propone la mejor secuencia
para generar el mejor código y consumir la menor cantidad de energía posible, siempre
priorizando el diseño sobre el consumo de energía.
En este contexto, hay trabajos que miden, controlan y comparan el consumo de energía delenguajes, bibliotecas, aplicaciones y algoritmos específicos. Noureddine et al. [2012] pre-senta la arquitectura POWERAPI que, junto con los módulos de energía, permite a losdesarrolladores calcular el consumo de energía de procesos y aplicaciones. Los primerosresultados muestran en tiempo de ejecución el consumo de energía de aplicaciones y al-goritmos. Algunos resultados indican que Java, usando las opciones predeterminadas, esbastante eficiente en términos de energía en comparación con otros lenguajes de progra-mación. Los autores también infieren que la eficiencia energética del lenguaje Pascal estáen el mismo nivel que C o C++. Sin embargo, otros resultados son más interesantes: Perles el lenguaje que consume más energía, OCaml es el segundo, luego Python y finalmenteProlog.
Trabajos más específicos evalúan el uso de prácticas comunes al desarrollar aplicaciones.
Por ejemplo, Procaccianti et al. [2016] evalúa dos prácticas para el desarrollo de software
energéticamente eficiente: el uso de consultas eficientes y poner la aplicación en reposo.
Por un lado, la limitación de la utilización de mecanismos de indexación u operaciones de
ordenamiento innecesarias (uso de palabras clave ORDER BY) puede aumentar el consu-
mo de energía de nuestras consultas. Por otro lado, un uso adecuado de la función Sleep
permite que la aplicación reduzca el uso de la CPU y mejore su eficiencia energética. En
general, los resultados muestran un impacto significativo y consistente de ambas prác-
ticas sobre el aumento de la eficiencia energética de las materias seleccionadas: Apache
WebServer y MySQL Database Server.
Otros trabajos interesantes estudian el uso de diferentes estructuras de datos y coleccio-nes. Primero, Hasan et al. [2016] evalúa el consumo de energía de operaciones comunesrealizadas en colecciones como Java List, Map y Set (por ejemplo, inserción, iteración,acceso aleatorio). Los resultados muestran que los tipos de datos alternativos para estasabstracciones difieren significativamente en términos de consumo de energía dependien-do de las operaciones. Los autores encontraron que elegir el tipo de colecciones incorrectopuede consumir 300% más de energía que la colección más eficiente. En segundo lugar,
55
Manotas et al. [2014] describe un soporte automatizado para optimizar el uso de energíade las aplicaciones mediante refactorings a nivel de código. Manotas et al. [2014] afirmaque las muchas capas de abstracción en las aplicaciones y las interacciones entre hard-ware y software sugieren que es difícil predecir cómo los refactorings afectan el consumode energía, que de hecho es nuestro objetivo en esta tesis para el caso de HPC en CPU.En consecuencia, Manotas et al. [2014] propone un framework que automáticamente a)genera versiones diferentes del mismo código combinando todas las instancias de colec-ciones, b) realiza ejecuciones supervisadas por energía de todas las versiones generadas,c) analiza los resultados, y d) genera una versión optimizada del original código. Sinembargo, el principal problema de este trabajo de investigación es que la recopilación yel procesamiento de muestras de energía puede tomar muchas horas dependiendo deltiempo de ejecución de la serie de pruebas, el número de repeticiones y el espacio deinvestigación.
3.4. Resumen
Los trabajos discutidos en este capítulo contribuyen a la introducción de dispositivos mó-viles en entornos computacionales como Grids y Clouds, tradicionalmente compuestosde PC y servidores. En la Sección 3.1 presentamos y analizamos diferentes trabajos cuyoobjetivo principal es ofrecer técnicas de Offloading de aplicaciones para ejecutar aplica-ciones intensivas en dispositivos móviles. El uso de Offloading presenta varias ventajas:primero, los usuarios pueden usar sus dispositivos como computadoras que ejecutanaplicaciones de recursos intensivos, mejorando el tiempo de ejecución de la aplicación, lalatencia o el consumo de energía; segundo, los científicos pueden aprovechar los sensoresy otros recursos en áreas remotas procesando datos en servidores. La principal limitaciónen esta área es que el procesamiento adicional necesario para determinar qué tareas soncandidatas a ser descargadas y cuál de estas tareas debe descargarse agrega tiempo adi-cional de ejecución y consumo de energía. Además, varios enfoques necesitan conoceralgunos parámetros, como los recursos necesarios para una tarea o la energía consumidapor una tarea para tomar decisiones, pero estos parámetros generalmente son desconoci-dos.
En la Sección siguiente (Sección 3.2) se presentaron diferentes enfoques para programar
tareas en Grid móviles. Este tipo de trabajos es una contribución importante para la co-
munidad científica, ya que hay miles de millones de dispositivos móviles en todo el mun-
do, lo que genera un increíble poder de cómputo. Luego, al enviar tareas pequeñas a
dispositivos móviles los científicos pueden ejecutar aplicaciones HPC sin la necesidad
de supercomputadoras costosas. Sin embargo, la mayoría de los trabajos en schedulers
distribuidos para áreas de dispositivos móviles son adaptaciones de trabajos anteriores
realizados para dispositivos fijos. Entonces, estas adaptaciones presentan numerosas li-
mitaciones y no consideran las peculiaridades del nuevo entorno relacionado con la falta
de fiabilidad de la conexión de los dispositivos móviles a la red, la cantidad limitada de
recursos disponibles y el suministro limitado de energía.
Finalmente, la Sección 3.3 muestra varias buenas prácticas para desarrollar aplicaciones
móviles. En esa Sección hay numerosos enfoques que investigan cómo reducir el consu-
56
mo de energía en dispositivos móviles (benchmarking, Code Smells, navegadores web,
entre otros). Además, la reducción de energía se puede realizar a nivel de aplicación, ni-
vel del sistema operativo y nivel de hardware. Sin embargo, todos estos estudios pueden
aplicarse para complementar cualquiera de los otros enfoques presentados anteriormen-
te. Esto significa que, teniendo en cuenta estas pautas y las buenas prácticas los desarro-
lladores pueden mejorar las técnicas de Offloading o las tácticas del Scheduler además
del código de la aplicación. Por ejemplo, al adaptar los sistemas HPC para que sean ami-
gables con la energía se puede mejorar la capacidad de un Grid, ejecutando así más tareas
con los mismos recursos. Además, saber qué operaciones consumen más energía puede
ser esencial para decidir si una tarea se ejecutará en un dispositivo móvil o fijo.
Además, varios intentos centrados en mejorar el consumo de energía de las aplicaciones
móviles se detallan en la Sección 3.3. Estos trabajos cubren varios temas y niveles (aplica-
ción, sistema operativo, hardware) que muestran la amplitud del área. Las aplicaciones
móviles se pueden mejorar teniendo en cuenta el uso de recursos (CPU, RAM, panta-
lla, etc.), el uso de la red, las funciones de red o los formatos de representación de los
diferentes elementos de la aplicación (imágenes, estilos, etc.). Como resultado, este inci-
piente área de investigación es extensa y, como tal, presenta interesantes líneas abiertas
de investigación. Como mencionamos anteriormente, las evaluaciones que se muestran
en la Sección 3.3 pueden ser útiles para tareas tan diversas como desarrollar aplicaciones
móviles, tomar decisiones en entornos computacionales, evaluar el impacto potencial de
una aplicación en un entorno de dispositivo móvil, entre otros.
Particularmente, la documentación operativa de Android tiene pautas para desarrollar
aplicaciones eficientes para dispositivos móviles, que cubre operaciones comunes tales
como getters/setters, loops y tipos de datos. De la misma manera, diferentes autores
evalúan el tiempo de ejecución y la mejora energética de la refactorización de algunas
malas prácticas bien conocidas llamadas Code Smellss. Sin embargo, estos trabajos tie-
nen algunas limitaciones: el primer trabajo solo se evalúa para las microoperaciones en
sí; luego, el impacto de aplicar estas pautas en aplicaciones reales no se evalúa; y, el se-
gundo no tiene evaluación experimental. Por otro lado, Thiagarajan et al. [2012] evalúa el
consumo de energía de los diferentes elementos de una página web individualmente y su
impacto en una página web real. Utilizando esa información, los desarrolladores pueden
evaluar diferentes intercambios de la aplicación de la guia propuesta. Aunque Thiagara-
jan et al. [2012] analiza el impacto de su enfoque en entornos reales, no puede emplearse
para el desarrollo de aplicaciones móviles de propósito general, lo cual es una limitación
significativa.
Otra área de investigación es HPC con dispositivos móviles. En esta área, una serie de
investigaciones evalúa el tiempo de ejecución o el consumo de energía. Una cantidad
considerable de trabajos evaluan el tiempo de ejecución de benchmarks conocidos y ope-
57
raciones de HPC, comparan diferentes lenguajes, pero ninguna evaluación hace experi-
mentos para evaluar las mejoras en aplicaciones reales. Por lo tanto, los desarrolladores
no pueden aprovechar efectivamente estos resultados al desarrollar aplicaciones. Final-
mente, en este contexto, una conclusión es que la mejora energética de diferentes micro-
benchmarks, que son parte de núcleos de aplicaciones científicas, junto con su impacto
en aplicaciones reales es un área inexplorada. Además, el análisis de refactorización se
puede complementar con un análisis de los trade-off de aplicar la refactorización en el
diseño de la aplicación contra el esfuerzo del desarrollador para aplicarlas. Además, co-
mo resultado secundario, se puede evaluar el impacto en el tiempo de ejecución, ya que
el consumo de energía y la ejecución del tiempo no tienen una relación lineal Rodriguez
et al. [2016a], Pinto et al. [2014].
Finalmente, este trabajo señala que varios problemas siguen abiertos. Por lo tanto, el usode dispositivos móviles como parte de un entorno distribuido, teniendo en cuenta el dise-ño y las mejoras del código para mejorar el rendimiento y el consumo de energía, puedeaumentar significativamente la cantidad de recursos disponibles. Como resultado, mejo-rar estas tres áreas principales diferentes (Offloading, schedulers distribuidos y modelosde desarrollo de software con eficiencia de energía) y combinarlas es un tema interesantetanto para la ciencia como para la industria.
58
Capıtulo 4
Micro-benchmarks y aplicaciones
Basado en una de las principales limitaciones para el desarrollo de aplicaciones para
dispositivos móviles, es decir, la capacidad limitada de las baterías, el objetivo princi-
pal de esta tesis es evaluar el consumo de energía de operaciones comunes en aplica-
ciones científicas para dispositivos móviles. Para minimizar el consumo de energía e,
indirectamente, el consumo de otros recursos como CPU y RAM, esta tesis busca encon-
trar la correspondencia entre las diferentes formas de implementar los mismos micro-
benchmarks y su correspondiente consumo de energía. Después de presentar nuestros
micro-benchmarks, discutimos el esfuerzo necesario para analizar y refactorizar los códi-
gos fuente.
Luego, la frecuencia con la cual los grupos de micro-benchmarks analizados aparecen en
aplicaciones reales puede verse en la Tabla 4.2, donde se estudian diferentes aplicacio-
nes científicas teniendo en cuenta las diversas operaciones presentes en ellas. Además, se
puede observar que estas aplicaciones son de gran importancia para la comunidad cientí-
fica ya que la mayoría de ellas se encuentran en un repositorio de aplicaciones de Satin1,
cuya utilidad se detallará en la Sección 4.2. Además, la Sección 4.1 explica el concepto
de micro-benchmark y sus peculiaridades en Java -el lenguaje de programación de alto
nivel de Android- y enumera y analiza cada grupo de micro-benchmarks seleccionados
para este trabajo. Como corolario, presentamos cómo los micro-benchmarks evaluados
también en aplicaciones científicas implementadas en servidores y qué aplicaciones re-
presentativas del usuario final real son particularmente probadas.
Cuadro 4.2: Resumen de aplicaciones de Ibis/Satin. El signo “+” representa una indicación cuan-titativa de la extensión de código que tiene ese grupo de micro-benchmarks
79
Aplicación AC OC OFA SH EH PDT MT AO Projectsource
FastFourier
Transform
- +++ +++ + + +++ - +++ Ibis/Satin
MatrixMultipli-
cation
- ++ - - + +++ +++ +++ Ibis/Satin
Knapsack + ++ - - ++ +++ +++ + Ibis/Satin
Nqueens - - - - + +++ +++ ++ Ibis/Satin
SequenceAlign-ment
- ++ ++ - - +++ ++ ++ GitHub
AC = Copia de arreglosOC = Creación de objetosOFA = Acceso a atributos deun objeto
SH = Manejo de StringsEH = Manejo de escepcionesPDT = Uso de tipos de datosprmitivos
MT = Recorrido de matricesAO = Operaciones aritmpe-ticas
Cuadro 4.3: Aplicaciones de casos de estudio. El signo “+” representa una indicación cuantitativade la extensión de código que tiene ese grupo de micro-benchmarks
Apkicación AC MT SH AO EH OFA OC PDT Projectsource
BayesNetworkClassifier
+ ++ - + - +++ +++ +++ Weka
GradientDescent
- +++ - ++ ++ +++ +++ +++ GitHub
AC = Copia de arreglosOC = Creación de objetosOFA = Acceso a atributos deun objeto
SH = Manejo de StringsEH = Manejo de escepcionesPDT = Uso de tipos de datosprmitivos
MT = Recorrido de matricesAO = Operaciones aritmpe-ticas
Cuadro 4.4: Aplicaciones de casos de estudio (Machine Learning). El signo “+” representa unaindicación cuantitativa de la extensión de código que tiene ese grupo de micro-benchmarkse
80
Capıtulo 5
Experimentos
Este capítulo presenta el hardware, el software y la metodología utilizados para los ex-
perimentos realizados en la tesis. Esta tesis mide el consumo de energía de 8 grupos de
micro-benchmarks y el impacto de las buenas prácticas obtenidas a partir de estos re-
sultados en siete aplicaciones científicas reales y dos aplicaciones móviles para usuarios
finales. Por lo tanto, a lo largo de este capítulo, se presentan una serie de limitaciones al
evaluar los micro-benchmarks en Java, que deben considerarse.
Entonces, para enfrentar estas limitaciones, decidimos utilizar un framework presentado
por Google llamado Caliper Google. Caliper es un framework de código abierto desarro-
llado por Google para escribir, ejecutar y obtener resultados de micro-benchmarks para
Java que minimiza los gastos generales introducidos por este lenguaje. Además, usamos
otro framework llamado Robotium para probar aplicaciones de usuario final. Además,
como mencionamos anteriormente, aprovechamos las ventajas del hardware especializa-
do para evaluar los micro-benchmarks y las aplicaciones reales en los servidores. Luego,
presentaremos el hardware utilizado en esta instancia junto con sus especificaciones.
Este Capítulo está dividido en 4 Secciones. La primera Sección 5.1 introduce Caliper,
el framework utilizado para realizar los experimentos. Luego, la Sección 5.2 muestra
la estructura general de la aplicación y detalla la metodología utilizada para evaluar
micro-benchmarks y aplicaciones HPC en dispositivos móviles. La Sección 5.3 presenta
el hardware introducido para probar micro-benchmarks y aplicaciones HPC en servido-
res. Además, se presenta el diseño de la aplicación. Finalmente, la Sección 5.4 muestra
la actualización de hardware para probar aplicaciones de usuario final en dispositivos
móviles.
81
5.1. Caliper
A diferencia de los lenguajes compilados tradicionales, el código compilado de Java (by-
tecode) es independiente de la plataforma. Las JVM proporcionan un entorno en el que
el bytecode de Java se puede ejecutar a) interpretando los bytecodes o b) siendo asistido
por un mecanismo just-time (JIT) mediante el cual se produce la traducción de bytecode
a assembly bajo demanda, mejorando el rendimiento. Además, las JVM tienen un intér-
prete equipado con un compilador dinámico que realiza una compilación optimizada de
las partes del programa más utilizadas Barisone et al. [2001]. No obstante, esto plantea
varios desafíos cuando se evaluan benchmarks en Java debido a que estos mecanismos
agregan "ruido":
realizar evaluaviones de rendimiento en JVM es difícil Sinschek et al. [2009] por-
que actúan como una capa de abstracción, lo que podría cambiar los resultados en
diferentes ejecuciones.
diferentes compiladores de Java hacen diferentes optimizaciones. Algunos compi-
ladores pueden detectar código muerto (código que no afecta a la salida) y elimi-
narlo. Se puede agregar código adicional que evite esta variación, pero esto podría
cambiar los resultados porque el código adicional agrega más código para ejecutar.
en Java, las iteraciones sobre un benchmark para obtener varias muestras estadís-
ticas de una operación de referencia incluyen una gran cantidad de compilación
dinámica. Las iteraciones posteriores suelen ser más rápidas porque incluyen me-
nos compilación y el código ejecutado está más optimizado Georges et al. [2007].
En este caso medir cuándo convergen las ejecuciones puede reducir el impacto.
el Garbage Collector puede activarse de forma asíncrona mientras se ejecuta un
código, lo que afecta el rendimiento del código porque el GC consume recursos
informáticos mientras libera la memoria.
la carga de clases al iniciar una aplicación puede causar que las primeras ejecucio-
nes consuman más recursos.
Después de analizar estos problemas, decidimos utilizar el framework de Caliper1 para
ejecutar nuestros experimentos. Caliper es un framework diseñado por Google para desa-
rrollar y ejecutar micro-benchmarks en Java. Si bien el enfoque principal de Caliper es la
medición de performance en micro-benchmarks, también se puede utilizar para tomar
medidas de diferente naturaleza como la asignación de memoria. La Figura 5.1 muestra
el formato general que debe tener un micro-benchmark Caliper para lograr su propósito.
1http://code.google.com/p/caliper/
82
Figura 5.1: Micro-benchmark
Este es un código muy simple, cuya única condición es extender la clase SimpleBenchmark
proporcionada por el framework, haciendo que el uso de este framework sea simple y
beneficioso.
Además de la clase donde se declara el micro-benchmark, hay más conceptos relaciona-
dos con Caliper que debemos tener en cuenta cuando desarrollamos micro-benchmarks.
Aquí hay algunos términos básicos que se necesitan para trabajar correctamente con Ca-
liper:
Benchmark method: es el método cuyo nombre debe comenzar con la palabra "time"
y cuyo propósito es ejecutar la parte del código desde el que quieren tomar las
métricas. Este método debe definirse dentro de la clase Benchmark que amplía la
clase SimpleBenchmark. Este es el método más importante para el desarrollador que
quiere obtener métricas.
Environment: es la descripción del hardware, sistema operativo y JRE en el que se
toma una medición. Es decir, son las condiciones de ejecución bajo las cuales se
prueba el micro-benchmark.
Medición: generalmente esta es la medición de performance.
Parámetro: se refiere a los valores que se inyectan en la clase de referencia con la
anotación @Param. Para cada parámetro, se puede configurar más de un paráme-
tro y luego probarse por separado y de forma automática. Entonces, estos valores
facilitan la experimentación con variaciones del mismo micro-benchmark de una
manera simple y rápida.
Reps: determina el número de veces que se debe ejecutar un escenario en cada in-
vocación. La ejecución repetida del mismo escenario permite obtener resultados ge-
neralizables y calcular valores estadísticos (como promedio y desviación estándar)
de ellos.
83
Escenario: es una instancia de un micro-benchmark de referencia completamente
especificado, es decir que tiene un valor específico para cada uno de los paráme-
tros definidos y para la variable Reps. Los escenarios tienen la propiedad de ser
ejecutables.
Ejecución: es el conjunto de escenarios ejecutados en lote en un único host. Es decir,
son ejecuciones realizadas en el mismo entorno.
Luego de presentar los conceptos básicos para trabajar con Caliper se presentan a conti-
nuación algunas buenas prácticas para la medición de micro-benchmarks. Estas prácticas
son para ejecutar siempre el mismo código dentro del cuerpo del micro-benchmark, y no
ingresar valores aleatorios ni usar el valor del contador de bucles dentro del cuerpo ya
que pueden introducirse desviaciones innecesarias. Después de definir correctamente el
microensayo para evaluar, puede tomar dos caminos diferentes para ejecutarlo:
1. La forma más sencilla de ejecutar los benchmarks de Caliper en Android es usar
una herramienta llamada Vogar.
2. Otra opción además de Vogar es compilar el micro-benchmark junto con Caliper y
sus dependencias en un archivo .jar y luego ejecutarlo en los dispositivos.
La metodología utilizada en este trabajo se basó en la segunda opción presentada.
5.2. Aplicación Android
Esta sección muestra el diseño del software de prueba para experimentos de HPC mó-
viles y su funcionamiento. El software de prueba es la aplicación móvil que contiene la
lógica necesaria para seleccionar y ejecutar micro-bechmarks y aplicaciones de prueba
científica. Vale la pena señalar que el software está disponible a pedido.
Una captura de pantalla del software se muestra en la Figura 5.2. El software tiene un
campo de texto configurable para indicar el número de ejecuciones para cada experi-
mento, que se ejecuta cuando se presiona el botón correspondiente. A continuación, la
Figura 5.2muestra las clases principales del software. En este diagrama, las clases App1 y
App2 crean instancias para cada aplicación de prueba y micro-benchmark. Este diagrama
incluye las clases principales del software y su funcionalidad. Sin embargo, hay clases
(por ejemplo, clases para registrar datos) que no se incluyen en el diagrama porque no
forman parte del núcleo del software. En este punto, es importante tener en cuenta que
cada prueba va desde e l100% de la carga de la batería hasta el estado de batería baja.
Cada clase del diagrama está explicada en los siguientes párrafos:
84
Figura 5.2: Aplicación Android: Diagrama de clases y Scrrenshot
App1, App2: Estas clases contienen la implementación de las aplicaciones y micro-
benchmarks, respectivamente. Las instancias de estas clases se ejecutan continua-
mente contando el número de ejecuciones hasta que la batería alcanza su límite de
capacidad baja (es decir, 15%).
Lock: es el Lock que permite que Runner y BatteryReceiver trabajen juntos cuando
se ejecuta el micro-benchmark. Además, evita que el Runner se ejecute cuando la
capacidad de la batería es inferior al 15%.
Runnable: es una interfaz proporcionada por Java como alternativa al uso directo
de la clase Thread. Las clases que lo implementan deben redefinir el método run(),
que permite la ejecución implícita de un micro-benchmark en un hilo diferente de
la aplicación principal.
Activity: es una clase proporcionada por el marco de Android que representa la
interfaz de usuario. En esta interfaz de usuario, el usuario selecciona diferentes pa-
rámetros de prueba, así como la prueba a ejecutar. Cuando el usuario selecciona la
85
ejecución que se llevará a cabo, la actividad es responsable de crear un servicio que
se ejecutará en segundo plano, impidiendo que una aplicación o micro-bechmark
deje de ejecutarse.
BatteryReceiver: esta clase extiende la clase BroadcastReceiver proporcionada por An-
droid para recibir cambios en el estado de la batería.
BatteryReceiverLowBATtery: esta clase extiende la clase BatteryReceiver. BatteryRecei-
verLowBattery recibe la condición de batería baja usando una clase IntentFilter -una
API Android- para este propósito. Cuando la capacidad de la batería alcanza el15%,
el micro-benchmark o la aplicación se detiene y las estadísticas de ejecución se al-
macenan.
BatteryService: este servicio tiene la responsabilidad de ejecutar la aplicación o micro-
benchmark seleccionada para ejecutarse. Este servicio contiene un atributo Power-
Manager que mantiene la CPU activa incluso si la pantalla se apaga.
SimpleBenchmark: es la clase que los micro-benchmark deben ampliar para usar el
marco Caliper.
Runner: esta clase extiende SimpleBenchmark e implementa Runnable para permitir
que los micro-puntos de referencia y las aplicaciones de prueba utilicen el marco
Caliper y ejecuten experimentos para drenar la batería. Luego, diferentes micro-
benchmarks y aplicaciones se extienden desde esta clase.
Finalmente esta lista incluye las clases principales que deben tenerse en cuenta cuando
se ejecuta el software de medición en Android.
5.2.1. Metodología
Teniendo en cuenta las restricciones de Caliper, desarrollamos una aplicación móvil para
contener todos los micro-benchmarks y aplicaciones de prueba para ejecutar. En la Sec-
ción 5.2 presentamos el diseño del software y su funcionamiento. Finalmente, nuestra me-
todología experimental fue la siguiente. Primero, medimos el número de ejecuciones de
cada micro-benchmark o aplicación de prueba en un ciclo de batería. Por ciclo de batería
nos referimos al tiempo transcurrido entre una batería completamente cargada y un es-
tado de batería baja. Usando esta metodología, cada micro-benchmark y cada aplicación
se evaluaron al menos 10 veces en cada tipo de dispositivo. Los dispositivos se cargaron
al 100% y todas las demás aplicaciones y servicios de los usuarios se desactivaron (ex-
cepto los esenciales para el sistema operativo); y las radios celulares/WiFi/Bluetooth y la
pantalla se apagaron para los experimentos. En una nota lateral, esta metodología es útil
para dispositivos modernos cuyas baterías no son extraíbles. Particularmente, usamos
6.1.9. Resumen micro-benchmarks en dispositivos móviles
Diferentes micro-benchmarks comúnmente encontrados en aplicaciones científicas ba-
sadas en Java fueron seleccionados para mostrar su consumo de energía en dispositi-
vos móviles Android. En todos los casos, estos experimentos muestran que los micro-
benchmarks que tienen un peor rendimiento en términos de tiempo consumen más ener-
gía también. Esta variación podría surgir como resultado de diferentes factores, que se
explicaron en detalle con los resultados para cada micro-benchmark. En resumen, los
resultados informados muestran que es mejor usar System.arrayCopy que una implemen-
tación manual de la misma funcionalidad. Además, algo tan trivial como el sentido de
recorrido de una matriz puede mejorar el rendimiento. Además, esta investigación refleja
la importancia de evitar operaciones con tipos de datos inmutables. Con respecto a los ti-
pos de datos numéricos, los desarrolladores deben analizar la aplicación y usar el tipo de
datos más específico para ahorrar energía, a veces a expensas de perder precisión. Otra
forma de reducir el consumo de energía es evitar el uso de excepciones en las aplicaciones
siempre que sea posible. Muchas veces, los objetos comunes pueden transmitir informa-
ción de error, lo que conduce a mecanismos para superar situaciones indeseables en la
aplicación sin lanzar una excepción. Finalmente, al referirnos a las primitivas básicas y
comunes en la programación OO, como el acceso al campo de objetos y la creación de ob-
jetos, mostramos que cuando estas primitivas no son necesarias, deben evitarse siempre
que sea posible, ya que consumen mucha energía. Por último, el uso de tipos de datos pri-
mitivos en lugar de sus clases correspondientes dio como resultado una pequeña mejora
energética.
105
1
2
4
8
16
32
64
128
256
512
1024
String Handling
Exception Handling
Object C
reation
Object Field Access
Arithmetic operations
Matrix Traversal
Array Copy
Primitive D
ata Type
Ga
in
Micro−benchmarks evaluation
Smartphone
Figura 6.3: Comparación de resultados de micro-benchmark
Por último, ofrecemos una comparación de la mejora de los grupos de micro-benchmarks,
ordenados de mayor a menor (ver la Figura 6.3).
6.2. ¿Cómo refactorizar aplicaciones?
En un intento de ilustrar el compromiso entre el esfuerzo de análisis de problemas y el
esfuerzo de ejecución de refactorización versus ganancia (en términos de energía) para
cada refactorización antes de presentar las aplicaciones de prueba, discutiremos el es-
fuerzo de los desarrolladores de aplicar las refactorizaciones asociadas a los grupos de
referencia. Aquí, "problema" se refiere a una imperfección del código que causa un con-
sumo de energía adicional.
Todos los grupos de micro-benchmarks necesitan un análisis previo antes de aplicar la
refactorización correspondiente. Esto se debe a que cualquiera de las refactorizaciones
implica un análisis semántico y un cambio de diseño; luego, podemos evaluar el esfuer-
zo necesario para realizar dos pasos: alcance del análisis y alcance de refactorización. De
esta forma, el alcance del análisis se refiere a la cantidad de unidades de código que los
desarrolladores deben analizar para determinar dónde refactorizar sin cambiar la fun-
cionalidad de la aplicación, es decir, si el análisis solo implica las secciones del código
donde aparece el problema (por ejemplo, creación de objeto). , llamada de método, etc.),
o incluye más elementos como métodos que llaman a esas secciones u otras clases. Por
106
otro lado, el ámbito de refactorización se refiere a cuántas secciones de código deben mo-
dificarse para aplicar la refactorización una vez que se han detectado las ocurrencias de
los problemas asociados. La Tabla 6.2 resume como se dan estos dos aspectos en nues-
tras refactorizaciones. En esta Tabla, los valores que pueden tomar los dos aspectos son
Sentencia, Método y Aplicación. En el ámbito de Análisis, el valor indica si los desarrolla-
dores deben analizar solo la semántica de las sentencias en los que aparece/se utiliza el
problema, la influencia del problema en el Método o su influencia en toda la Aplicación.
Por el contrario, los valores para el ámbito de Refactorización indican si los desarrollado-
res deben modificar solo las sentencias donde aparece el problema o si la refactorización
implica más esfuerzo.
Como podemos ver, algunas de las refactorizaciones requieren menos esfuerzo en ambos
aspectos, lo que significa que son más fáciles de analizar y aplicar. Primero discutimos
estas refactorizaciones. Comenzando con el acceso a los atributos de un objeto, donde la
refactorización implica la ruptura de la encapsulamiente de datos, su alcance de Análisis
y la determinación del alcance de Refactorización son tareas triviales que incluso pueden
automatizarse. En este caso, los desarrolladores solo deben tener en cuenta las restriccio-
nes de encapsulamiente y, luego, deben cambiar todas las llamadas al método Getter por
el acceso directo al atributo siempre que sea posible. Esta refactorización se puede aplicar
para cambiar solo los accesos de una clase a sus propios atributos o adicionalmente para
cambiar los accesos a atributos de clase externos (en este caso el atributo tiene que ser
un atributo público) pero el alcance del Análisis y el de Refactorización están circuns-
critos a la clase problemática. A continuación, para cambiar las clases contenedoras por
tipos de datos primitivos es necesario analizar si se utiliza algún método específico de
la clase; después de esto, el esfuerzo necesario para aplicar la refactorización es mínimo:
los desarrolladores deben cambiar el tipo de atributo y cambiar los métodos utilizados
por la operación equivalente en el tipo de datos primitivo. De esta forma, la refactori-
zación solo afecta las sentencias donde aparece el atributo y los desarrolladores pueden
detectarlas buscando el nombre del atributo. Ahora, después de presentar estas dos refac-
torizaciones, analizamos el resto de las refactorizaciones, que inherentemente necesitan
más esfuerzo en relación con los dos aspectos analizados.
Primero, antes de usar bibliotecas o métodos integrados de Java, es necesario tener co-
nocimiento sobre las bibliotecas y métodos existentes. Además, detectar las secciones de
código que pueden ser reemplazadas por funcionalidades incorporadas o métodos de
biblioteca no es una tarea trivial o automatizable. Por otra parte, las alternativas son di-
versas, y lo más apropiado depende de varios factores de ingeniería de software. Luego,
los desarrolladores deben analizar todo el código fuente teniendo en cuenta sus cono-
cimientos previos, ya que es posible que no tengan ninguna pista sobre dónde y cómo
deben aplicar la refactorización. El segundo grupo que mencionamos en la última sub-
sección es el recorrido de la matriz. Aplicar la refactorización de recorrido es una tarea
107
Grupos de Microbenchmark/Refactoring Alcance del análisis Análisis del Refactoring
Acceso a atributos de un objeto Sentencia Sentencia
Uso de tipos de datos primitivos Sentencia Sentencia
Copia de arreglos Aplicación Aplicación
Recorrido de matrices Método Método
Manejo de Strings Aplicación Sentencia
Operaciones arotméticas Aplicación Sentencia
Manejo de excepciones Método Aplicación
Creación de Objetos Aplicación Sentencia
Cuadro 6.2: Refactoring application effort
108
trivial en términos de código, pero no es una tarea trivial a la hora de analizar la semán-
tica del recorrido. Por ejemplo, el recorrido en la multiplicación de matrices no puede
cambiar. Sin embargo, después de un análisis, los desarrolladores podrían transponer las
matrices y, luego, cambiar el sentido del recorrido. Esto significa que incluso cuando el
paso de análisis no es una tarea fácil, existen diferentes estrategias que pueden emplear-
se para allanar el camino para aplicar la refactorización. Aún así, el alcance del análisis
cubre solo la sección donde se atraviesa la matriz y se utilizan sus elementos.
El siguiente grupo presentado es manejo de strings. Para generalizar este grupo, debe-
mos mencionar que los strings en Java se implementan a través de una clase inmutable.
Los desarrolladores deben evitar las clases inmutables cuando los valores de los objetos
cambian con frecuencia; aunque son útiles para preservar un valor de objeto. Entonces,
los desarrolladores necesitan tener conocimiento previo sobre la aplicación para deci-
dir si este tipo de clases es realmente necesario. Por ejemplo, son útiles en aplicaciones
concurrentes porque no pueden cambiar el estado y, como consecuencia, no pueden co-
rromperse por la interferencia de subprocesos o estar en un estado incoherente. Luego,
los desarrolladores deben analizar el código fuente en toda su extensión porque estas
clases pueden aparecer como parámetros de método, atributos de método, atributos de
clases, entre otros, lo que requiere un gran esfuerzo. El ámbito de refactorización, por
otro lado, se reduce, ya que los cambios debidos a este tipo de refactorizaciones implican
modificaciones de código a nivel de declaración.
Finalmente, las otras refactorizaciones (que corresponden a los grupos Operación arit-
mética, Manejo de excepciones y Creación de objetos) necesitan un análisis de código
previo aún más detallado. En otras palabras, los cambios dependen de la semántica de
las operaciones y del alcance de cada objeto. Es decir:
Para cambiar la precisión de una variable numérica los desarrolladores deben co-
nocer la precisión necesaria en esa aplicación o método.
Para evitar una excepción los desarrolladores deben saber cómo manejar el error o
la situación excepcional a lo largo de cualquier posible cadena de llamada al método
afectado.
Para reutilizar un objeto, los desarrolladores deben asegurarse de que el objeto no
se utilizará después de ese momento, es decir, los objetos se pueden usar durante
la ejecución en cualquier momento. Luego, los desarrolladores deben conocer la
secuencia de ejecución del código para ver si el mismo objeto se usa nuevamente o
puede ser reemplazado por otro.
Este último caso es uno de los más difíciles de detectar porque los desarrolladores tienen
que analizar el comportamiento del código en tiempo de ejecución. Además, el manejo
109
de excepciones es el único grupo en el que el ámbito de refactorización incluye no solo
el método M en el que se lanza la excepción sino también los métodos que llaman a M,
es decir, si la refactorización implica devolver un mensaje de error, es necesario cambiar
el métodos en la pila que se ven afectados por este error porque también tienen que
gestionar el mensaje de error.
6.3. Resultados de las aplicaciones de prueba en dispositivos mó-
viles
Después de obtener los resultados de los grupos de micro-benchmark, aplicamos estos
resultados a una selección de aplicaciones científicas reales obtenidas del proyecto Ibis/-
Satin. El objetivo principal de estas evaluaciones fue medir el impacto real de las buenas
prácticas en aplicaciones reales. En las siguientes subsecciones, explicamos los resultados
obtenidos para cada aplicación de prueba presentada en la sección 4.2. En esta sección,
evaluamos cada aplicación de prueba original (es decir, no modificada) contra una ver-
sión refactorizada en la que aplicamos cada primitiva de refactorización relacionada con
los grupos de micro-benchmarks previos. Medimos las mismas aplicaciones de dos ma-
neras: la primera medición no tiene en cuenta las capacidades multi-core de los dispositi-
vos móviles, mientras que la segunda usa esta capacidad para ejecutar dos instancias de
las aplicaciones al mismo tiempo. Las aplicaciones multi-core se ejecutan en tablets Acer
A100 que tienen un procesador de doble núcleo.
Las Tablas 6.3, 6.4 y 6.5 muestran los resultados de ejecutar las aplicaciones de prueba
en smartphones y tablets, respectivamente. Las Tablas 6.1, 6.3, 6.4, 6.5 y 6.6 presentan el
tiempo de ejecución individual para cada experimento. Con estos valores, podemos ver
que, al menos en nuestras condiciones experimentales, la reducción del uso de energía
implica menos tiempo de ejecución, pero no linealmente. En las siguientes subsecciones
analizamos estos resultados.
6.3.1. Fast Fourier Transform (FFT)
Como mencionamos en la Subsección 4.2.1, al refactorizar el código fuente el principal
cambio en esta aplicación fue la eliminación de las clases inmutables. Esto fue posible
mediante la modificación de una clase llamada Complex,que era inmutable en la aplica-
ción original. En la nueva versión, las instancias de clase Complex pueden cambiar los va-
lores de sus atributos sin crear una gran cantidad de instancias inmutables de dicha clase.
Sin embargo, en la aplicación refactorizada debemos tener especial cuidado cuando tra-
bajamos con estos objetos porque no podemos modificar los valores de los atributos de
los objetos en uso. Además, la precisión de los atributos se redujo sin alterar el resultado
110
Aplicación Versión Número de
ejecuciones
(promedio)
Reducción
de consumo
de energía
(%)
Desviación
estándar
(%)
Tiempo de
ejecución
(ms)
Reducción
en tiempo
de
ejecución
(%)
FFTOriginal 2,958,624 1.8 10.04
Refactorizada 4,501,692 34 2.7 6.64 33
MMULTOriginal 265,358 2.6 113.02
Refactorizada 620,446 57 2.0 49.09 56
KnapsackOriginal 764,696 1.3 38.56
Refactorizada 54,558,035 98 2.6 0.54 98
Cuadro 6.3: Resultados de aplicaciones (I5500 smartphone)
111
Aplicación Versión Número de
ejecuciones
(promedio)
Reducción
de consumo
de energía
(%)
Desviación
estándar
(%)
Tiempo de
ejecución
(ms)
Reducción
en tiempo
de
ejecución(%)
FFTOriginal 14,154,500 2.1 3.20
Refactorizada 21,848,470 35 2.9 2.08 35
MMULTOriginal 822,499 0.9 51.65
Refactorizada 1,398,069 40 1.3 33.69 34
KnapsackOriginal 2,887,815 2.0 15.79
Refactorizada 184,605,003 98 2.9 0.25 98
Cuadro 6.4: Resultados de aplicaciones (ViewPad 10s tablet)
112
Aplicación Versión Número de
ejecuciones
(promedio)
Reducción
de consumo
de energía
(%)
Desviación
estándar
(%)
Tiempo de
ejecución
(ms)
Reducción
en tiempo
de
ejecución
(%)
FFTOriginal 19,665,230 2.4 1.54
Refactorizada 35,238,914 44 1.4 0.91 40
MMULTOriginal 1,468,103 3.9 20.35
Refactorizada 3,948,948 62 0.9 7.70 62
KnapsackOriginal 4,303,748 3.24 6.81
Refactorizada 324,865,596 98 2.2 0.06 98
Cuadro 6.5: Resultados de aplicaciones (Acer A100 tablet)
113
Aplicación Versión Número de
ejecuciones
(promedio)
Reducción
de consumo
de energía(%)
Desviación
estándar
(%)
Tiempo de
ejecución
(ms)
Reducción
en tiempo
deejecución
(%)
FFTOriginal 12,202,676 2.9 2.24
Refactorizada 24,663,150 50 4.2 1.06 49
MMULTOriginal 1,363,580 1.5 17.50
Refactorizada 3,726,860 63 4.2 6.10 65
KnapsackOriginal 3,576,953 1.4 6.89
Refactorizada 241,204,637 98 4.9 0.10 98
Cuadro 6.6: Resultados de aplicaciones multicore (Acer A100 tablet)
114
0
50000
100000
150000
200000
250000
300000
350000
400000
450000
500000
(a) Samsung Galaxy I5500
Executions/1
0
OriginalModified
0
30000
60000
90000
120000
150000
180000
210000
240000
(b) ViewPad 10s
Executions/1
00
OriginalModified
0
40000
80000
120000
160000
200000
240000
280000
320000
360000
400000
(c) Acer A100
Executions/1
00
OriginalModified
Figura 6.4: FFT (Dispositivos Móviles)
115
de la aplicación. En resumen, obtuvimos una mejora favorable modificando los objetos
y disminuyendo la precisión de los atributos. Esta mejora fue constante en los diferentes
tipos de dispositivos móviles.
La Tabla 6.3 y la Figura 6.4 (a) muestran los resultados con las ejecuciones usando el
Samsung Galaxy I5500. De forma similar, la Tabla 6.3 y la Figura 6.4 (b) muestran los
resultados con la tablet ViewPad 10s. Por último, la Tabla 6.3 y la Figura 6.4 (c) muestran
los resultados con la tablet Acer A100. Las reducciones en el uso de energía son 34%, 35%
y 44% para el primer, segundo y tercer caso, respectivamente. Finalmente, la mejora en el
tiempo de ejecución es similar a los valores de reducción de uso de energía, a saber, 33%,
35% y 40%, respectivamente.
6.3.2. Matrix multiplication (MMULT)
Como en el caso anterior, el aspecto principal para evitar en esta aplicación fue la crea-
ción de objetos. Sin embargo, en esta aplicación la instanciación de diferentes clases se
realiza al comienzo de la ejecución (no se realiza progresivamente durante la ejecución).
Entonces, la principal diferencia con el caso anterior es que durante la ejecución de la FFT
hubo muchos objetos creados y utilizados de inmediato por la aplicación, mientras que
en MMULT las instancias de Matrix se utilizan desde el principio hasta el final de la eje-
cución . No usar una estructura recursiva tiene la ventaja de requerir menos objetos en la
memoria. La estructura de la matriz se rediseñó disminuyendo el número de creaciones
de objeto.
Presentamos los resultados obtenidos después de las ejecuciones. Los resultados del smartp-
hone Galaxy I5500 se muestran en la Tabla 6.3 y gráficamente en la Figura 6.5 (a). De la
misma manera, presentamos los resultados de la tablet ViewPad 10s en la Tabla 6.3 y la
Figura 6.5 (b). Finalmente, la 6.3 y la Figura 6.5 (c) muestran los resultados para la tablea
Acer A100. En esta aplicación se obtuvo una gran mejora ejecutando la versión refactori-
zada. Sin embargo, la variación en los resultados depende de la capacidad de RAM del
dispositivo, ya que el smartphone utilizado para las pruebas puede almacenar menos
objetos en la memoria que las tablets debido a la RAM total disponible.
Los porcentajes de reducción en el consumo de energía son del 57% para el smartphone,
del 40% para la tablet ViewPad 10s y del 62% para la tablet Acer A100. En base a es-
tos resultados, podemos concluir que una diferencia del 10% o más en la reducción del
consumo de energía implica una diferencia significativa en cómo se utiliza la energía de
la batería. Al evaluar esta aplicación obtenemos un 56%, 34% y 62% de reducción en el
tiempo de ejecución en el I5000, el ViewPad 10s y el Acer A100, respectivamente.
116
0
70000
140000
210000
280000
350000
420000
490000
560000
630000
700000
(a) Samsung Galaxy I5500
Executions/1
0
OriginalModified
0
15000
30000
45000
60000
75000
90000
105000
120000
135000
150000
165000
(b) ViewPad 10s
Executions/1
0
OriginalModified
0
40000
80000
120000
160000
200000
240000
280000
320000
360000
400000
440000
(c) Acer A100
Executions/1
0
OriginalModified
Figura 6.5: MMULT (Dispositivos Móviles)
6.3.3. Knapsack Problem (KP)
Para completar el análisis de los experimentos presentamos los resultados de la última
aplicación refactorizada, Knapsack Problem. En esta aplicación redujimos la cantidad de
objetos en la memoria a la mitad. En la versión original se crea una instancia de la clase
OrcaRandom y una de la clase Knapsack, mientras que en la nueva versión de la aplica-
ción de prueba creamos solo una instancia de la clase Knapsack. Otro cambio significa-
tivo para esta aplicación de prueba fue la reducción de llamadas a métodos, eliminando
métodos que fueron llamados por un solo método.
Finalmente, se logran excelentes resultados con estas simples modificaciones. Los resul-
tados en el smartphone se presentan numéricamente en la Tabla 6.3 y gráficamente en
la Figura(a). Además, la Tabla 6.4 y la Figura 6.6 (b) muestran los resultados de la tablet
ViewPad 10s. Finalmente, la Tabla 6.5 y la Figura 6.6 (c) muestran los resultados para el
Acer A100. Estos resultados implican una reducción significativa del consumo de energía
(superior al 90%).
117
0
60000
120000
180000
240000
300000
360000
420000
480000
540000
600000
(a) Samsung Galaxy I5500
Executions/1
00
OriginalModified
0
20000
40000
60000
80000
100000
120000
140000
160000
180000
200000
220000
(b) ViewPad 10s
Executions/1
,000
OriginalModified
0
35000
70000
105000
140000
175000
210000
245000
280000
315000
350000
(c) Acer A100
Executions/1
,000
OriginalModified
Figura 6.6: Knapsack (Dispositivos Móviles)
6.3.4. Aplicaciones Multi-core
En esta Subsección, analizamos el impacto de la aplicación de refactorizaciones en apli-
caciones multi-core. Usamos las mismas aplicaciones que evaluamos antes de evaluar la
variación entre el uso de un solo núcleo y el uso de todos los núcleos. Como podemos
ver en la Figura 6.7 y en la Tabla 6.6, al usar toda la capacidad de la CPU, el número de
ejecuciones disminuyó tanto para la aplicación original como para larefactorizada, pe-
ro la reducción de consumo de energía fue similar en comparación con el caso en el que
utilizamos solo un núcleo. Esto significa que las refactorizaciones tienen el mismo impac-
to en el resultado final, independientemente de la cantidad de núcleos. La disminución
en el número de ejecuciones es una consecuencia del costo de ejecutar una aplicación
de múltiples subprocesos porque la creación y ejecución de subprocesos toman tiempo e
introducen latencia en el procesamiento del código.
6.3.5. Resumen
Después de obtener los primeros resultados (impacto de los micro-benchmarks indivi-
duales en los dispositivos móviles, Sección 6.1) realizamos más estudios de casos en
118
0
40000
80000
120000
160000
200000
240000
280000
320000
360000
400000
440000
480000
520000
Mmult
Executions/1
0
OriginalOriginal MultiCore
ModifiedModified MultiCore
(a) MMULT
0
40000
80000
120000
160000
200000
240000
280000
320000
360000
400000
440000
480000
FFT
Executions/1
00
OriginalOriginal MultiCore
ModifiedModified MultiCore
(b) FFT
0
35000
70000
105000
140000
175000
210000
245000
280000
315000
350000
385000
420000
Knapsack
Executions/1
,000
OriginalOriginal MultiCore
ModifiedModified MultiCore
(c) Knapsack
Figura 6.7: Multi-core evaluation (Dispositivo Movil)
119
Aplicación Original vs refactorizadaIncremento en el número de ejecuciones
At 0.01? At 0.05?
FFT
Smartphone " "
ViewPad 10s tablet " "
Acer A100 tablet $ "
Multi-core $ "
MMULT
Smartphone " "
ViewPad 10s tablet " "
Acer A100 tablet " "
Multi-core " "
KP
Smartphone " "
ViewPad 10s tablet " "
Acer A100 tablet $ "
Multi-core $ "
Cuadro 6.7: Test de significancia estadística: Variación en número de ejecuciones
los que se midieron los impactos de las refactorizaciones en tres aplicaciones científi-
cas reales: FFT, MMULT y Knapsack Problem. En estas aplicaciones, los resultados para
diferentes dispositivos fueron similares. Esto significa que incluso en los casos en los que
hubo algunas variaciones en el uso de energía, la aplicación de la refactorización pro-
puesta reduce el consumo de energía. Estas variaciones son causadas por la diferencia
en la capacidad de RAM de los dispositivos, los smartphones utilizados en los experi-
mentos tienen menos capacidad de RAM que las tablets. Como consecuencia, el GC de
Android se activa en intervalos de tiempo más cortos en smartphones que en tablets, lo
que consume más energía.
Para validar estos resultados nosotros utilizamos el test Mann-Whitney U. Para cada tri-
pla T =< d, a,v,>, donde v ∈ {Smartphone,ViewPad10s, AcerA100, AcerMulti − Core},
a ∈ {FFT, MMult,KP} y v ∈ {original,re f actored}, una lista de número de ejecuciones.
Estudiamos la fuente de las reducciones de energía ejecutando pruebas estadísticas para
comparar, dado dos posibles triples T1 =< d, a,′ original′ > y T2 =< d, a,′ re f actored′ >, si
hay diferencias significativas estadísticamente en las medianas del número de ejecucio-
nes antes y después de aplicar refactorizaciones.
Como resultado, la Tabla 6.10 muestra los resultados de la prueba en los niveles de sig-
nificancia de 0.01 y 0.05. Observamos que los códigos refactorizados (T2) tienden a eje-
120
cutarse más veces que los códigos originales (T1). De la Tabla anterior se confirma que
cada aplicación refactorizada puede ejecutarse más veces que la misma aplicación sin
refactorizaciones, particularmente en el nivel de significancia 0.05.
6.4. Resultados de Micro-benchmarks (Servidores)
La Tabla 5 muestra el consumo promedio de energía (en jouless) de cada versión demicro-benchmark. Como explicamos en el Capítulo 5, para cuantificar la reducción deluso de energía por micro-benchmark utilizamos la siguiente fórmula: