1 comentarios

 
GN⁺ 2023-12-04
Opiniones de Hacker News
  • Al ver la historia de las generaciones ARM que usaba Raspberry Pi, sorprende lo viejo que es ese chip.
    Incluso para 2014, cuando salió la Raspberry Pi B+, el núcleo ARM1176 que usaba era de 2003, así que ya tenía 11 años.
    Por eso no es raro que, al compilar en otra plataforma como una Raspberry Pi más reciente, pueda ser necesario especificar flags de arquitectura para generar código compatible.
    Pero si incluso al compilar en la propia Raspberry Pi B+ no se selecciona por defecto la arquitectura correcta, eso parece un error de configuración en los valores predeterminados de la distribución.

    • Recuerdo que la Pi original usaba chips que habían sobrado de TV boxes.
      Ese tipo de productos casi nunca incluye más capacidad de cómputo de la necesaria, por una cuestión de precio.
    • Desde el principio era un producto pensado como computadora de bajo costo.
    • En realidad no se compiló en una B+.
      El artículo dice: “tomé el binario desde el host de compilación, una Pi 4B mucho más rápida, e intenté ejecutarlo en este dispositivo viejo; entonces apareció una illegal instruction”.
      Es parecido a intentar ejecutar en una PC vieja con Windows XP un .EXE compilado con un MSVC moderno en Windows 11.
      Probablemente toda la distribución de Pi que corre en la Pi 4B tampoco funcione en una B+, y hasta el kernel podría haberse compilado de la misma manera.
  • Parece que el post o el artículo no lo tratan con claridad, pero ¿no es esto un bug?
    Buscando bugs de LLVM encontré uno que parecía casi el mismo problema, pero era de 2012 y está cerrado. Al ver los últimos comentarios parecía posible que en realidad no se hubiera corregido, aunque solo lo revisé por encima y podría haberlo malinterpretado.
    https://github.com/llvm/llvm-project/issues/13989
    Al volver a mirar, al final del post dice que si se pasa explícitamente el target se obtiene un programa que funciona. Entonces parece más bien algún tipo de bug de configuración; en Unix pensaría que el target predeterminado debería ser el procesador actual, pero no estoy seguro.
    El bug que enlacé parece haber sido un problema donde se generaba código incorrecto aun configurando bien el target, y por suerte parece que ahora no estamos ante esa situación.

    • Correcto. El bug enlazado era un problema donde, aunque se le decía al compilador que apuntara a armv6, emitía instrucciones armv7.
      El problema de Rachel se resolvió diciéndole al compilador que apuntara a armv6, así que ese bug ya fue corregido y parece ser independiente de este caso.
    • Obviamente es un bug, pero parece que la autora, en vez de reportarlo, escribió un post de blog con un título algo clickbait y terminó con “qué raro”.
  • ClickHouse, la base de datos en la que trabajo, hace bastante esfuerzo por mantener compatibilidad con hardware muy antiguo.
    El binario ARM estándar requiere Armv8.2 de 2016 y se puede usar en modelos desde Raspberry Pi 2 en adelante. El binario x86 corre en hardware de alrededor de 2010 que tenga SSE4.2 y las instrucciones pclmul* para CRC rápido.
    También compilamos binarios para sistemas que solo tienen Armv8.0 y SSE2, pero no los probamos en CI. El script de instalación rápida descarga y descomprime el binario adecuado para el host de destino.
    En general, siento que es difícil encontrar el equilibrio entre la compatibilidad hacia atrás y aprovechar las funciones de CPU de las generaciones modernas de AArch64.
    https://en.wikipedia.org/wiki/AArch64
    Había una cantidad sorprendentemente grande de instituciones con presupuestos ajustados, por ejemplo universidades de países emergentes, y usuarios aficionados sin capacidad para actualizar hardware.
    Técnicamente, fue bastante molesto que los flags de CPU de /proc/cpuinfo no siempre correspondan con los flags -march= que se le pasan al compilador. Por ejemplo, aparecen distintos como "lrcpc" y "rcpc".
    Para que esto funcione bien, en la práctica hay que mantener dos conjuntos de flags.

    • En esos casos, creo que a todos les conviene ofrecer varias compilaciones para que los clientes puedan elegir la más cercana a su arquitectura.
  • Es muy probable que el problema sea que en el paquete clang-13 actual de bookworm cambió el target configurado.
    En concreto, en bullseye y clang-11 el target predeterminado es armv6k-unknown-linux-gnueabihf, mientras que en bookworm y clang-13 es arm-unknown-linux-gnueabihf.
    O tal vez cambió en LLVM el valor predeterminado de esa configuración de compilación.

  • No parece que haya sido un cambio intencional.
    Como se mencionó en comentarios cercanos sobre /etc/env.d/gcc, es bastante probable que sea una forma de leer información desde el entorno.
    El triple predeterminado probablemente sería algo como arm-unknown-linux si clang no encuentra ni recibe información más específica, pero parece que se rompió el mecanismo que le indica un objetivo más específico.
    Esto podría significar que no hay buildbot para ARMv6, o que sí lo hay, pero allí la configuración implícita todavía funciona bien.
    LLVM es un muy buen compilador cruzado. Se puede compilar desde casi cualquier objetivo hacia cualquier otro sin mayores problemas.
    Clang es menos atractivo en ese sentido. Si fue compilado con soporte para el objetivo y se le puede indicar correctamente para qué objetivo compilar, probablemente lo maneje bien. En este artículo, aunque la suposición fue incorrecta, al darle más información funcionó correctamente.
    La situación con las bibliotecas de runtime es peor. Aunque se compile para un objetivo como armv4, hay que encontrar una libc y demás que correspondan, y puede que haya que indicarle al compilador la ubicación de esas bibliotecas y headers; en esta parte los detalles todavía no están claros.

    • La mayoría de las distribuciones y compiladores, en la práctica, abandonaron el soporte para ARMv6 hace algunos años.
      Tuve un problema parecido al compilar binarios para un NAS Synology antiguo.
    • ¿Por qué Clang tendría que leer información desde /etc/env.d/gcc?
  • clang/clang++ leen las flags de objetivo y los perfiles desde /etc/env.d/gcc, y mantener eso correctamente es responsabilidad del sistema operativo.
    En este sistema operativo parece que esa gestión no se hizo bien.
    Mi SBC Gentoo ARM, basado en la arquitectura armv4 más antigua, sigue funcionando bien incluso con las actualizaciones más recientes de gcc/clang.
    grep CTARGET /etc/env.d/gcc -r
    /etc/env.d/gcc/armv4tl-softfloat-linux-gnueabi-11.3.0:CTARGET="armv4tl-softfloat-linux-gnueabi"

    • /etc/env.d es un directorio específico de Gentoo que define variables de entorno predeterminadas para las sesiones de usuario.
      Clang no tiene una función para leer ese directorio, así que no hay que asumir que existe en otras distribuciones.
      La configuración del compilador de Gentoo simplemente lee la variable de entorno CTARGET para elegir el objetivo, y Gentoo usa /etc/env.d para establecer ese valor.
  • El texto no dice si es Debian o Raspbian, ni, si es Debian, si se trata del port armel o armhf.
    Sin esa información, no tiene mucho sentido discutir con qué conjunto de instrucciones compila LLVM. Eso depende de la configuración de objetivo nativo de LLVM.
    Como referencia, llvm-toolchaim-snapshot de Debian todavía soporta armel, que usa ARMv5T como línea base. Sin embargo, actualmente hay un bug aparte en la biblioteca OpenMP de LLVM que impide que la compilación tenga éxito.

    • Lo extraño es que el propio binario de Clang está compilado con un conjunto de instrucciones compatible con la Pi B+, pero aun así no apunta a un conjunto de instrucciones compatible con la Pi B+.
      Eso sí que es raro. Como no se supone que se use como compilador cruzado, en teoría host y objetivo deberían ser iguales.
      Probablemente la imagen sea Raspbian. No parece haber razón para no asumirlo.
  • Sería útil conocer la salida del comando dpkg-architecture y el contenido del archivo /etc/os-release.
    Sin eso, es difícil hacer comentarios útiles.

  • El título lamentablemente es sensacionalista.
    Esto es un cambio del objetivo predeterminado, y clang todavía puede compilar binarios para la Pi B+.
    Solo hay que especificar explícitamente la arquitectura. Por eso parece mejor cambiar un poco el título para que quede más claro que se trata de un cambio de configuración predeterminada.

    • Si al compilar en la propia máquina objetivo no puede generar un binario para esa máquina, no me parece tan sensacionalista.
  • Me parece interesante que, al depurar por qué un programa no se ejecuta en ARM, aparentemente se pueda encarar más o menos de esta forma.
    Tengo una build de Unity para Linux que no se ejecuta dentro de un contenedor; aunque le pase la flag amd64 al ejecutar Docker, Unity mono intenta hacer una llamada al sistema que no puede usar.
    Encontré una solución alternativa y todavía no lo depuré. Activé el modo de desarrollo y cambié la configuración de build para que no use mono.
    Algún día debería volver a investigarlo para aprender más.