
PAQ8PX ahora corre en procesadores ARM
Hola a todos,
En los pasados días, trabajé para lograr que el compresor PAQ8PX funcione en procesadores ARM. Inicialmente el programa no quería compilar porque dependía de unas instrucciones SSE2/SSSE3 que no existen en la arquitectura ARM. Esto requirió de añadir código NEON, que es el equivalente para esta arquitectura. Una vez logrado, el programa compiló y ejecutó sin problemas en los procesadores Snapdragon 845 y 865 CPU’s de mis celulares Samsung Galaxy S9+ y S20 Ultra:


Probé el programa usando la aplicación Termux y corriendo ubuntu del proyecto AndroNix.
Los cambios que fueron hechos incluyeron añadir unas directrices #elif
para ver si estabamos compilando en procesadores ARM. Esto fue añadido debajo de la directríz #id
que verifica si estamos compilando en un procesador i386 o x86_64. Estas directrices verifican y añaden los archivos immintrin.h
y arm_neon.h
, respectivamente.
Hubieron 2 archivos principales que requirieron portar el código de SSE3/SSSE3 a NEON. En realidad, estos cambios no eran necesarios, pero al hacerlos, nos permite usar el procesador al máximo, usando estas instrucciones nativas.
Comencé modificando el archivo Mixer.hpp
, que ya tenía código para SSE2 y AVX2.

Podemos ver que añadí 2 funciones principales y 2 de ayuda de la traducción:


Los archivos SimdMixer.hpp
y MixerFactory.cpp
requirieron añadir unos else if
y otra condición para soportar los nuevos cambios:
SimdMixer.hpp




MixerFactory.cpp

El otro archivo que requirió portar código fue Bucket.hpp
. También refactoricé el código para que ejecute código correspondiente a la arquitectura que estamos usando y que es especificada o detectada al ejecutar el programa:


También porté el código de SSSE3 a AVX2:


La función que tenía el código SSSE3 ahora se llama findSsse3
:


Y aquí tenemos el código NEON:


Si no se detecta ningun SIMD o se especifica uno al ejecutar el programa, se ejecuta el código de la función findNone
:

Finalmente, aquí está la función find
original. Esta fue extendida para aceptar un segundo argumento con el SIMD a usar:

Este cambió también requirió modificar la función find
en los archivos ContextMap.cpp
y ContextMap2.cpp
para que acepten este argumento.
simd.hpp
Este archivo requirió añadir unas directrices #ifdef
:

Y si estamos compilando en ARM, devolvemos el valor 11:

Finalmente, en el archivo paq8px.cpp
, actualicé el parametro -simd
para que acepte el argumento neon
:





Y esos fueron los cambios que realicé.
La última versión en estos momentos es paq8px v187. Esta versión es complatible con procesadores ARM e incluyen algunos arreglos.
Puedes seguir el progreso del programa en el foro encode.su haciendo click aquí.