¿Cómo mterp (Dalvik VM) organiza su bucle de interpretación de bytes?
Estoy estudiando Android Dalvik VM y encuentro una pregunta cuando leo el código mterp en el archivo vm / mterp / out / InterpC-portable.cpp. En realidad es el bucle de intérprete principal de dalvik vm para interpretar el código de byte en el archivo dex. Si escribí este archivo, elegiré una estructura de switch-case para hacer esto:
while (hasMoreIns()) { int ins = getNextIns(); switch(ins) { case MOV: //interprete this instruction ... break; case ADD: ... break; ... default: break; } }
Sin embargo, lo que mterp utiliza es muy diferente con mis pensamientos, utiliza un código mágico (para mí) como este:
- ¿Las bibliotecas externas hacen las aplicaciones más lentas?
- KitKat tarda 6 segundos más que Froyo para reaccionar a TextToSpeech.speak () en primera llamada
- Lectura rápida de enteros pequeños endian de archivo
- Rendimiento de bucle ArrayList en ART (Android Runtime Environment)
- Apague TODA la optimización de Dalvik VM
FINISH(0); HANDLE_OPCODE(OP_NOP) FINISH(1); OP_END HANDLE_OPCODE(OP_MOVE) ... OP_END ...
I google y encontrar parece ser un modificado "roscado" ejecución de estilo, que diferente con estilo de cambio de caso y tiene un mejor rendimiento, ya que eliminar la sucursal operación en while loop. Pero todavía no puedo entender este código y por qué es mejor en el rendimiento. ¿Cómo encuentra el siguiente código para el intérprete?
- Diferencias de rendimiento entre SQLite en Android e iOS
- ¿Por qué Android prefiere las clases estáticas?
- Cómo dibujar varias líneas con el dedo? (Androide)
- Acceder directamente a los campos estáticos en lugar de llamar a un método getter estático, ¿es más rápido?
- La respuesta de Json es un android muy lento
- ListView vs LinearLayout
- Vista de reciclador - cambia el tamaño de la vista de elemento mientras se desplaza (para efecto de carrusel)
- Android desplácese hacia arriba ocultar vista y desplácese hacia abajo mostrar el efecto de vista como twitter
Como un poco de guía, el directorio está lleno de archivos preprocesados y no es lo que yo llamaría una gran cosa para leer, si usted está tratando de averiguar el código. La fuente (per se) que corresponde a InterpC-portable.cpp
es el contenido de los directorios portable
y c
.
En términos de cómo el código hace el envío de opcode, querrá ver la definición de la macro FINISH
, en portable/stubdefs.cpp
:
# define FINISH(_offset) { \ ADJUST_PC(_offset); \ inst = FETCH(0); \ if (self->interpBreak.ctl.subMode) { \ dvmCheckBefore(pc, fp, self); \ } \ goto *handlerTable[INST_INST(inst)]; \ }
Esta macro se utiliza al final de cada definición de código de operación y sirve como el equivalente de una instrucción switch (opcode)
. En pocas palabras, esto lee la unidad de código de instrucción apuntada por el PC – inst = FETCH(0)
– toma el opcode fuera de ella – INST_INST(inst)
– y usa ese opcode como índice en la tabla de direcciones de todos los opcodes. La dirección se ramifica directamente con la sentencia goto
.
El goto
es un "goto computado", que es una extensión no estándar de GCC. Puedes leerlo en el manual de GCC, y también puedes encontrar un poco sobre el tema en la presentación que di en Dalvik internals en Google IO en 2008. (Encontrarlo en https://sites.google.com/site / Io / dalvik-vm-internals .)
Mi charla también aborda el tema de las características de rendimiento de esta técnica. En pocas palabras, se ahorra una cierta cantidad de ramificación y juega relativamente bien con la predicción de rama. Sin embargo, hay mejores maneras de escribir un intérprete (como cuento en la charla, y como los intérpretes de Dalvik específicos de la CPU funcionan).
Y para un poco más del contexto más grande, la compilación de bytecode a las instrucciones nativas de la CPU en general va a resultar en una ejecución más rápida que incluso el intérprete más bien afinado, asumiendo que tiene suficiente RAM para contener el resultado compilado. El trazado basado en Dalvik JIT que se introdujo en Froyo fue destinado a hacer un compromiso en el que modestas cantidades de RAM adicional se utilizaron para lograr ganancias de rendimiento razonablemente fructífero.
- Desarrollo de Android con editor de notas y línea de comandos
- Agregar nuevo contacto mediante la intención con varios números de teléfono