Con ARMv6 vs ARMv7 llego un poco tarde a esta discusión de tecnología que en el fondo es relativa a las capacidades del hardware y a qué podemos esperar del software que lo aprovecha.
Las arquitecturas ARM más comunes hasta hace poco en el mundo de las miniordenadores eran estas dos, aunque ARMv8 está creciendo con fuerza y a corto medio plazo será la que domine. Las diferencias ente ARMv6 (ARM versión 6) y ARMv7 (ARM versión 7) no son claras por el hecho de que los diseños de la empresa ARM son modulares. Por lo que ciertas capacidades son opcionales y no tienen que ser implementadas, podemos tener por tanto un chip ARMv7 muy capado peor que un ARMv6 con todos los extras.
En primer lugar, las diferencias en el conjunto de instrucciones básicas de ARM son insignificantes. Los registros centrales de ARMv6 y ARMv7 son los mismos. ARMv7 es compatible con ARMv6, por lo que los binarios compilados para ARMv6 también deberían funcionar en ARMv7. ARM está orientado a una arquitectura estrictamente RISC (del inglés Reduced Instruction Set Computer, en español Computador con Conjunto de Instrucciones Reducidas). Por lo tanto, el conjunto de instrucciones básicas de ARM sólo puede realizar operaciones muy sencillas. Para cosas complejas, los micros ARM tienen módulos de tipo coprocesador: las llamadas extensiones.
Sin embargo, las extensiones son opcionales y el fabricante del chip puede decidir no implementarlas. Las diferencias principales de ARMv6 vs ARMv7 están exactamente en varias extensiones de procesador. Muchas de las extensiones típicas de ARMv7 fueron creadas cuando los chips ARMv6 estaban usándose y en algunas de las subversiones de ARMv6 pueden encontrarse algunas de estas mejoras. Esto se puede ver en detalle en esta tabla de la Wikipedia: Arquitectura ARM – Familias.
ARMv7 estás dividido recientemente en 3 perfiles: ARMv7-A, ARMv7-R y ARMv7-M. Los perfiles difieren en los modos de acceso a la memoria, latencia o control de interrupciones:
- El perfil A está más cerca del sistema clásico de PC, con el sistema operativo y las aplicaciones encima. Este es el que encontramos en todas estas placas de tipo mini ordenador.
- Por otra parte, el perfil R está a medio camino del A y el R es para «Tiempo Real», o sea, de respuesta rápida pero con sistema operativo y aplicaciones preparadas para ese entorno exigente.
- Y por último, el perfil M se acerca más al comportamiento del microcontrolador con procesamiento determinístico de tiempo, típicamente sin sistema operativo.
Los juegos de extensiones más importantes son: VFP, Thumb technology y NEON.
VFP
Vector Floating Point, vectores de punto flotante para el procesamiento vectorial (y escalar) de operaciones en coma flotante. Aunque es opcional, casi siempre se implementa. Para ARMv6 y ARMv7 es de facto un coprocesador estándar en coma flotante, que permite sumar, restar, dividir y multiplicar con precisión simple y doble. También permite a la CPU realizar un lote de cálculos aritméticos con una sola instrucción. Sin embargo, los cálculos se realizan secuencialmente, uno por uno. Normalmente tendremos estos casos:
- ARMv6: Incluye VFPv2 opcionalmente y normalmente se implementa siempre.
- ARMv7: Incluye VFPv3 opcionalmente y también normalmente se implementa siempre. VFPv3 trae varias mejoras menores sobre la versión 2. Principalmente añade nuevas capacidades a las instrucciones de ensamblador VCVT y VMOV. Algunas operaciones con valores de coma flotante pueden funcionar más eficientemente debido a la mejora.
Thumb technology
El conjunto de instrucciones ARM para v6 y V7 incluye instrucciones de 32 bits. Sin embargo, no todas las instrucciones necesitan tanto espacio. Esto puede conducir a la ineficiencia durante la carga de instrucciones en memoria y a un código de máquina innecesariamente voluminoso. Thumb technology, tecnología de pulgar (no me preguntéis de dónde viene el nombre), está destinada a optimizar el tamaño del código de la máquina mediante la sustitución de algunas de instrucciones de 32 bits por sus alternativas de 16 bits.
- ARMv6: Incluye la primera versión de la tecnología Thumb. Esta versión daba problemas al procesar instrucciones combinadas de 32 bits y Thumb de 16 bits. El procesador debe cambiar entre el modo ARM y el modo Thumb (lo que lleva tiempo) o dividir instrucciones de 32 bits en unas pocas instrucciones Thumb de 16 bits. Esto produce ineficiencias y lleva a que muchos ejecutables se compilen con las extensiones Thumb desactivadas cuando se compila para ARMv6.
- ARMv7: Incluye tecnología Thumb-2. Esta versión añade instrucciones de 32 bits al modo Pulgar. Es importante notar que la función de la instrucción «comprimida» es idéntica a la instrucción «completa», solo cambia la codificación en memoria. Ahora es posible combinar libremente instrucciones de 16 y 32 bits sin pérdida de rendimiento. Por lo tanto, ARMv7 puede beneficiarse de la tecnología Thumb y obtener un aumento considerable del rendimiento.
NEON
Las extensiones NEON son de tipo SIMD (Single Instruction, Multiple Data) destinadas a procesar operaciones aritméticas por lotes. Del mismo modo, como en el caso de los VFP, los operandos se introducen como vectores en una sola instrucción. A diferencia del VFP, NEON procesa todo el lote en paralelo, ahorra el tamaño del código y acelera el cálculo. NEON es muy útil cuando se codifica/decodifica multimedia, gráficos 2D/3D, etc. Sin embargo, hay que tener en cuenta que NEON puede trabajar con valores flotantes con precisión simple.
- ARMv6: No incluye motor NEON.
- ARMv7: Incluye NEON opcionalmente y normalmente se implementa siempre.
Conclusión del enfrentamiento ARMv6 vs ARMv7
ARMv7 puede ser una plataforma más rápida y eficiente, pero siempre que incluya las extensiones nuevas. Por ejemplo, las extensiones NEON pueden asumir funciones VFP, para valores de coma flotante en precisión simple y hacer esas operaciones en paralelo. Para aprovecharlas algunos compiladores pueden vectorizar algunas operaciones aritméticas para emplear NEON tanto como sea posible. Pero una vez más, no funciona perfectamente en todos los casos.
Si aún queréis más rollo de este tipo podéis leer también: Una historia de Cortex. Cuando se trata de rendimiento en bruto es más importante la versión del núcleo de Cortex que la arquitectura real.
Sin embargo, arquitectura y extensiones son muy importantes si se afina la configuración del compilador para un hardware en particular. Ahí vimos por ejemplo la diferencia entre Raspbian armsf del principio y la gran mejora que supuso armhf que se compiló para aprovechar las extensiones VFP.