GCC vs. Clang/LLVM: An In-Depth Comparison of C/C++ Compilers

Visual C++, GNU Compiler Collection (GCC), and Clang/Low Level Virtual Machine (LLVM) are three mainstream C/C++ compilers in the industry. Visual C++ proporciona interfaces gráficas de usuario (GUI) y es fácil de depurar, pero no es adecuado para plataformas Linux. Por lo tanto, este documento compara principalmente GCC con Clang/LLVM.

GCC es un compilador de lenguaje de programa desarrollado por GNU. Es un conjunto de software libre publicado bajo la Licencia Pública General de GNU (GPL) y la Licencia Pública General Reducida de GNU (LGPL). Es un compilador oficial para los sistemas GNU y Linux, y un compilador principal para compilar y crear otros sistemas operativos UNIX.

LLVM contiene una serie de componentes de compiladores modulares y cadenas de herramientas. Puede optimizar los lenguajes y enlaces de los programas durante la compilación, el tiempo de ejecución y el tiempo de inactividad, y generar código. LLVM puede servir como fondo para compiladores en varios idiomas. Clang es un compilador de C, C++, Objective-C u Objective-C++ compilado en C++ basado en LLVM y publicado bajo la licencia Apache 2.0. Clang se utiliza principalmente para proporcionar un rendimiento superior al de GCC.

A través del desarrollo e iteración a largo plazo, GCC, Clang y LLVM se han convertido en compiladores maduros en la industria. Entonces, ¿qué compilador es mejor? ¿Cuál deberíamos usar para compilar y construir programas y sistemas?

Importancia de un buen compilador

Todos los procesadores modernos tienen tuberías superescalar y largas, y estructuras internas complejas, y soportan unidades de extensión vectorial en la arquitectura de Equipo de Conjunto de Instrucciones Complejo (CISC) o Equipo de Conjunto de Instrucciones Reducido (RISC). Para muchos programas que contienen núcleos de uso intensivo de computación general, los programadores pueden usar comandos de extensión vectorial para mejorar en gran medida el rendimiento de ejecución del programa. Por ejemplo, en las operaciones de matriz y vector, los comandos de multiplicación y suma combinados se utilizan para mejorar el rendimiento y la precisión. Los comandos de máscara de bits se utilizan para el procesamiento de ramas en operaciones vectoriales. Sin embargo, para lograr el mayor rendimiento, los programadores y compiladores todavía necesitan gastar mucho esfuerzo para manejar tareas con modos de acceso a memoria complejos y núcleos no estándar.

Además, los estándares de los lenguajes avanzados modernos abstraen constantemente los detalles del hardware subyacente y las estructuras de datos para generar código general que es más lógico y matemático, en lugar de instrucciones de operación específicas y rutas de acceso a la memoria. Los estándares de C++ son cada vez más expresivos y abstractos. Python es popular porque es más legible y expresivo, incluso a costa de una velocidad de ejecución más baja. Una mayor expresividad aumenta la carga del compilador para generar un buen código de ensamblado a partir de las complejas estructuras compiladas por los programadores. El compilador debe ser más inteligente y trabajar más duro para maximizar el rendimiento mediante el uso del código. No todos los compiladores pueden hacer esto. Al seleccionar un compilador, primero debemos considerar si el mismo segmento de código puede generar comandos de ensamblado más eficientes.

Además de generar programas ejecutables de alto rendimiento, los compiladores modernos también deben tener un alto rendimiento. Un proyecto de software de gran tamaño en C++ puede contener de cientos a miles de unidades de traducción individuales. Cada unidad de traducción puede contener miles de líneas de código. El código C++ también puede utilizar un gran número de tecnologías de programación basadas en plantillas. Estas tecnologías requieren que el compilador transfiera información relevante varias veces para generar un archivo de destino. La compilación de proyectos de C++ de gran tamaño puede tardar varias horas, y se deben enviar simultáneamente varios cambios mutuamente dependientes durante el desarrollo. Cada envío requiere que los desarrolladores recompilen la mayoría de las bibliotecas de código. Por lo tanto, los compiladores más rápidos (herramientas de compilación) son críticos para lograr una alta productividad para equipos grandes.

En términos de extensión de lenguaje, los sistemas informáticos modernos con múltiples núcleos, capacidades de procesamiento vectorial y aceleradores proporcionan capacidades superiores a las capacidades naturales de los lenguajes de programación comunes. Por lo tanto, los marcos de computación de alto rendimiento (HPC) específicos, como OpenMP y OpenACC, pueden llenar este vacío. Estos frameworks proporcionan interfaces de programa de aplicaciones (API) que los programadores pueden usar para expresar paralelismo en el código. El compilador y la biblioteca de tiempo de ejecución correspondiente deben asignar el código paralelo a la arquitectura del procesador. Muchos proyectos de HPC dependen de los estándares OpenMP y OpenACC, que están siendo extendidos por desarrolladores y fabricantes de hardware. Por lo tanto, los compiladores deben mantenerse al día con el desarrollo de estándares de extensión de lenguaje.

En conclusión, un buen compilador nos permite centrarnos en el proceso de programación, en lugar de luchar contra sus deficiencias. Puede soportar los últimos estándares de lenguaje, generar comandos optimizados a partir del código más abstracto y compilar el código fuente en menos tiempo.

Historia de desarrollo de GCC

Antes de aprender GCC, primero debe comprender el Proyecto GNU. Richard Stallman lanzó el Proyecto GNU en 1984 para construir un sistema de software de código abierto similar a UNIX. El sistema operativo GNU no ha evolucionado mucho a lo largo del tiempo. Sin embargo, ha incubado muchas herramientas de software de código abierto excelentes y útiles, como Make, Sed, Emacs, Glibc, GDB y GCC también. Estos núcleos de Linux y software de código abierto de GNU juntos constituyen el sistema GNU / Linux. Al principio, GCC proporcionaba compiladores estables y confiables, basados en el lenguaje de programación C, para el sistema GNU. Su nombre completo es GNU C Compiler. Más tarde, más lenguajes (como Fortran, Obj-C y Ada) fueron soportados, y el nombre completo de GCC cambió a GNU Compiler Collection.

GCC-1.0 fue lanzado por Richard Stallman en 1987, hace más de treinta años. Desde la perspectiva del software, es muy antiguo. Alguien recopiló los registros de desarrollo de GCC entre 1989 y 2012, y produjo un video animado de treinta minutos (GNU Compiler Collection dev history 1989-2012), demostrando intuitivamente el proceso de desarrollo de GCC. Podemos aprender sobre la historia de desarrollo de GCC de sus versiones:

  • GCC-1.0: lanzado por Richard Stallman en 1987.
  • GCC-2.0: lanzado en 1992 y compatible con C++. Más tarde, la comunidad de GCC se dividió porque Richard Stallman definió a GCC como un compilador de C confiable del sistema GNU y pensó que GCC en ese momento era suficiente para el sistema GNU y el enfoque de desarrollo debería cambiarse de GCC al sistema GNU en sí. Otros desarrolladores importantes esperaban seguir mejorando el CCG y hacer desarrollos y mejoras más radicales en varios aspectos. Estos desarrolladores activos dejaron la comunidad de GCC en 1997 y desarrollaron la bifurcación EGCS.
  • GCC-3.0: Obviamente, los desarrolladores generalmente tenían un fuerte deseo de buenos compiladores. La bifurcación EGCS se desarrolló sin problemas y se hizo reconocida por más y más desarrolladores. Finalmente, EGCS fue utilizado como la nueva red troncal de GCC y GCC-3.0 fue lanzado en 2001. La comunidad dividida se volvió a fusionar de nuevo, pero la influencia de Richard Stallman se había debilitado hasta cierto punto. Además, el Comité Industrial del CCG había comenzado a decidir la dirección de desarrollo del CCG.
  • GCC-4.0: lanzado en 2005. Esta versión se integró en la Arquitectura de Almacenamiento en Serie en Árbol (SSA), y GCC evolucionó para ser un compilador moderno.
  • GCC-5.0: lanzado en 2015. Más tarde, se ajustó la política de versiones de GCC y se lanzó una versión principal cada año. Un beneficio inesperado es que el número de versión corresponde al año. Por ejemplo, GCC-7 se lanzó en 2017, y GCC-9 se lanzó en 2019.

Ahora, el desarrollo de GCC ha entrado en la»crónica moderna». Frente a la presión competitiva de LLVM, la comunidad del CCG ha realizado activamente muchos ajustes, como acelerar la compilación y mejorar la información de alerta de compilación. En los últimos 30 años, GCC ha evolucionado de un retador en la industria de los compiladores a un compilador convencional para sistemas Linux, y ahora se enfrenta al desafío de LLVM. Afortunadamente, la comunidad del CCG está haciendo ajustes para acelerar el desarrollo del CCG. Podemos esperar que la competencia entre las dos tecnologías de compilación continúe proporcionando a los desarrolladores de software mejores compiladores.

La historia de desarrollo de Clang y LLVM

LLVM se originó a partir de la investigación de Chris Lattner sobre UUIC en 2000. Chris Lattner quería crear una tecnología de compilación dinámica para todos los lenguajes estáticos y dinámicos. LLVM es un tipo de software de código abierto desarrollado bajo la licencia BSD. La versión inicial 1.0 fue lanzada en 2003. En 2005, Apple Inc. contrató a Chris Lattner y su equipo para desarrollar lenguajes de programación y compiladores para computadoras Apple, después de lo cual el desarrollo de LLVM entró en la vía rápida. A partir de LLVM 2.5, se lanzaron dos versiones menores de LLVM cada año (generalmente en marzo y septiembre). En noviembre de 2011, LLVM 3.0 fue lanzado para convertirse en el compilador predeterminado de XCode. XCode 5 comenzó a usar Clang y LLVM 5.0 de forma predeterminada. La política de versiones se ajustó para LLVM 5.0 y versiones posteriores, y se lanzan dos versiones principales cada año. La versión estable actual es 8.0.

El nombre de LLVM se abrevió por primera vez de Máquina Virtual de Bajo Nivel. Como este proyecto no se limita a la creación de una máquina virtual, a menudo se cuestiona la abreviatura LLVM. Después de que se desarrolló LLVM, se convirtió en un término colectivo para muchas herramientas de compilación y tecnologías de herramientas de bajo nivel, haciendo que el nombre fuera menos apropiado. Los desarrolladores decidieron abandonar el significado detrás de esta abreviatura. Ahora LLVM se ha convertido en la marca oficial, aplicable a todos los proyectos bajo LLVM, incluidas las bibliotecas LLVM Intermediate Representation (LLVM IR), LLVM debugging tools y LLVM C++ standard. LLVM se puede utilizar como compilador tradicional, compilador JIT, ensamblador, depurador, herramienta de análisis estático y para otras funciones relacionadas con lenguajes de programación.

En 2012, LLVM ganó el premio al sistema de software de la Asociación para Maquinaria Informática (ACM), junto con sistemas tradicionales como UNIX, WWW, TCP/IP, TeX y Java. LLVM simplifica enormemente la implementación de nuevas cadenas de herramientas de lenguaje de programación. En los últimos años, muchos lenguajes de programación nuevos como Swift, Rust y Julia han utilizado LLVM como su marco de compilación. Además, LLVM se ha convertido en el compilador predeterminado para sistemas Mac OS X, iOS, FreeBSD y Android.

Clang

Clang está diseñado para proporcionar un compilador de interfaz que puede reemplazar a GCC. Apple Inc. (incluido el siguiente) ha estado usando GCC como compilador oficial. GCC siempre ha funcionado bien como compilador estándar en la comunidad de código abierto. Sin embargo, Apple Inc. tiene sus propios requisitos para las herramientas de compilación. Por un lado, Apple Inc. se agregaron muchas características nuevas para el lenguaje Objective-C (o incluso, más tarde, el lenguaje C). Sin embargo, los desarrolladores de GCC no aceptaron estas características y asignaron baja prioridad al soporte para estas características. Más tarde, simplemente se dividieron en dos ramas para un desarrollo separado, y en consecuencia la versión GCC lanzada por Apple Inc. es mucho anterior a la versión oficial. Por otro lado, el código GCC está altamente acoplado y es difícil de desarrollar por separado. Además, en versiones posteriores, la calidad del código continúa disminuyendo. Sin embargo, muchas de las funciones requeridas por Apple Inc. (como el apoyo a un Entorno de Desarrollo Integrado mejorado (IDE)) debe llamar a GCC como un módulo, pero GCC nunca proporciona dicho apoyo. Además, la Exención de Bibliotecas de tiempo de ejecución de GCC limita fundamentalmente el desarrollo de LLVM GCC. También limitado por la licencia, Apple Inc. no se puede usar LLVM para mejorar aún más la calidad de generación de código basado en GCC. Por lo tanto, Apple Inc. decidió escribir el sonido de interfaz de los lenguajes C, C++ y Objective-C desde cero para reemplazar completamente a GCC.

Como su nombre indica, Clang solo admite C, C++ y Objective-C. El desarrollo comenzó en 2007 y el compilador de C se completó por primera vez. Clang para Objective-C cloud se utilizará completamente para el entorno de producción en 2009. El soporte para C++ también progresó rápidamente. Clang 3.3 totalmente compatible con C++ 11, Clang 3.4 totalmente compatible con C++ 14 y Clang 5 totalmente compatible con C++ 17, y todos estaban significativamente por delante de GCC en ese momento.

Clang/LLVM y Comunidad de GCC

Al igual que otras comunidades de software de código abierto, la comunidad de GCC está dominada por entusiastas del software libre y hackers. En el proceso de desarrollo, los mecanismos de gestión y participación de la comunidad del CCG se forman gradualmente en la actualidad. Actualmente, la comunidad de GCC es una sociedad de conocimiento relativamente estable y bien definida en la que cada persona tiene roles y deberes claros:

  • Richard Stallman y la Fundación para el Software Libre (FSF): Aunque rara vez participan en la gestión de la comunidad de GCC, Richard Stallman y la FSF todavía están separados en asuntos legales y de licencias.
  • Comité Industrial del CCG: Gestiona los asuntos de la comunidad del CCG, los temas de desarrollo del CCG independientes de la tecnología y el nombramiento y anuncio de revisores y mantenedores. Actualmente tiene 13 miembros.
  • Mantenedores globales: Dominan las actividades de desarrollo del CCG. En cierta medida, determinan la tendencia de desarrollo del CCG. Actualmente, hay 13 mantenedores mundiales, que no todos ocupan cargos en el Comité Industrial del CCG.
  • Mantenedores de Frontend, middle-end y backend: Son los mantenedores de frontend, backend y otros módulos. Son responsables del código del módulo GCC correspondiente, y muchos de ellos son los principales contribuyentes al código del módulo. Vale la pena señalar que los revisores generalmente se clasifican en este grupo. La diferencia es que los revisores no pueden aprobar su propio parche, mientras que los mantenedores pueden enviar sus propias modificaciones dentro de su ámbito de responsabilidad sin la aprobación de los revisores.Colaboradores
  • : Son los grupos de desarrolladores más extensos de la comunidad de GCC. Después de firmar el acuerdo de derechos de autor, cualquier desarrollador puede solicitar el permiso de Escritura después de la aprobación de la comunidad y luego enviar el código por sí mismo.

Al igual que otras comunidades de código abierto, la comunidad madura de GCC ya no está dominada por hackers. Las empresas comerciales comenzaron a desempeñar papeles importantes en la comunidad, como reclutar desarrolladores y patrocinar reuniones de desarrollo. Actualmente, la comunidad de GCC está dominada por los siguientes tipos de empresas comerciales: proveedores de sistemas

  • , incluidos principalmente RedHat y SUSE.
  • Proveedores de chips, principalmente Intel, ARM, AMD e IBM (PowerPC).
  • Proveedores especializados, como CodeSourcery y proveedores de servicios de cadena de herramientas como AdaCore basados en el lenguaje Ada. CodeSourcery tuvo una brillante historia y reclutó a muchos desarrolladores famosos, pero lo rechazó después de que Mentor lo adquiriera.

En la comunidad actual de GCC, los proveedores de chips dominan el desarrollo de backend, mientras que los proveedores de sistemas guían otras áreas de desarrollo. En términos de desarrollo de la comunidad, el código GCC está actualmente alojado en su propio servidor SVN. Se proporciona una API de Git para facilitar el desarrollo y el envío. La revisión de parches es similar a la de la comunidad del Núcleo Linux y utiliza el formulario de Lista de correo. Como se mencionó anteriormente, la comunidad del CCG es una sociedad de conocidos relativamente estable (o cerrada). La comunidad tiene básicamente de 150 a 200 colaboradores activos cada año y celebra una conferencia de desarrolladores en septiembre de cada año. En septiembre de 2019, la conferencia de desarrolladores se celebrará en Montreal, Canadá.

Comunidad LLVM

La comunidad LLVM es una comunidad de compiladores amigable con los noobs. Responde rápidamente a las preguntas de nuevos usuarios y revisiones de parches. Esto también es la base y la fuente para las discusiones posteriores de la Fundación LLVM y la adopción del Código de Conducta de la Comunidad LLVM, y causa una serie de discusiones políticamente correctas.

Todos los proyectos y problemas de LLVM se discuten a través de la lista de correo electrónico DevExpress, y el envío de código se notifica a través de la lista de correo electrónico de confirmaciones. Todos los errores y modificaciones de funciones se rastrean a través de la lista de errores. Los parches enviados se recomiendan para las ramas maestras. El estilo cumple con los estándares de codificación LLVM y la revisión del código se realiza a través de Phabricator. Actualmente, el repositorio de código LLVM ha sido migrado a GitHub.

A diferencia de la comunidad GCC, la comunidad LLVM solo tiene la Fundación LLVM. La Fundación LLVM tiene ocho miembros. Además de administrar los asuntos de la comunidad de LLVM, cada miembro de la Fundación LLVM tiene que guiar los problemas de desarrollo de LLVM relacionados con la tecnología. Actualmente, la presidenta es Tanya Lattner, la esposa de Chris Lattner. El propio Chris Lattner también es miembro de la fundación y tiene un fuerte control sobre la comunidad LLVM y la dirección de desarrollo de LLVM.

La política de revisión de código en la comunidad LLVM es básicamente la misma que en la comunidad GCC. La diferencia es que, debido al rápido desarrollo de LLVM, muchos contribuidores no tienen permiso de acceso a commit, y tienen que enviar su código a través de los mantenedores. Actualmente, las comunidades Clang y LLVM cuentan con más de 1.000 contribuyentes cada año. Generalmente, las conferencias de desarrolladores se llevan a cabo en abril y octubre anualmente. La conferencia de desarrolladores en octubre de 2019 se llevará a cabo en San José, EE.

La licencia LLVM se cambia de Licencia UIUC a Licencia Apache 2.0 con excepciones LLVM. Se utiliza principalmente para resolver el problema de que la biblioteca de tiempo de ejecución LLVM se basa en una licencia MIT y la autorización de patente requerida para el proyecto es demasiado extensa. Bajo esta licencia, LLVM permite a cualquier persona derivar productos comerciales de LLVM sin restricciones, y no requiere que ningún derivado proporcione código fuente abierto, promoviendo así el uso extensivo de LLVM, que incluye:

  1. La descarga o el uso de LLVM en su totalidad o en parte para fines personales, internos o comerciales. La capacidad de modificar el código LLVM sin contribuir de nuevo al proyecto.
  2. La creación de un paquete o versión de lanzamiento que contenga LLVM. La asociación de LLVM con código autorizado por todas las demás licencias principales de código abierto (incluidas BSD, MIT, GPLv2 y GPLv3).
  3. Al volver a distribuir LLVM, debe conservar el aviso de derechos de autor. No puede eliminar ni reemplazar el encabezado de derechos de autor. El archivo binario que contiene LLVM debe contener el aviso de copyright.

Comparación de rendimiento entre GCC y LLVM

Arquitectura: x86_64
Procesador: Intel (R) Xeon (R) Platinum 8163 CPU a 2,50 GHz
Caché de datos L1: 32 KB
Caché L2: 1.024 KB
Caché L3: 33.792 KB
Memoria: 800 GB
Sistema operativo: Alibaba Group Enterprise Linux Server versión 7.2 (Paladín) Núcleo: 4.9.151–015.ali3000.alios7.compilador x86_64
: Clang/LLVM 8.0 GCC8.3.1

Benchmark

SPEC CPU 2017 es un conjunto de herramientas de prueba de subsistemas de CPU para probar la CPU, la caché, la memoria y el compilador. Contiene 43 pruebas de cuatro categorías, incluyendo SPECspeed 2017 INT y FP que prueban la velocidad de enteros y la velocidad de operación de punto flotante y SPECrate 2017 INT y FP que prueban la tasa de concurrencia de enteros y la tasa de concurrencia de punto flotante. Clang no admite el lenguaje Fortran. Por lo tanto, en este ejemplo, los programas C/C ++ en el conjunto de pruebas de velocidad de ESPECIFICACIONES se utilizan para probar la diferencia de rendimiento de un solo núcleo entre los programas binarios generados por Clang y GCC. En la siguiente tabla se enumeran los conjuntos de ESPECIFICACIONES CPU2017 C y C++:

CINT2017 SpeedCFP2017 Speed600.perlbench_s619.lbm_s602.gcc_s644.nab_s605.mcf_s620.omnetpp_s623.xalancbmk_s625.x264_s631.deepsjeng_s641.leela_s657.xz_s

Métodos de prueba

El marco de automatización LLVM-lnt se utiliza para realizar la prueba y comparar el rendimiento. Se ejecuta de la misma manera que runcpu de la CPU SPEC. Antes de que LLVM-lnt se ejecute, se borra la caché (echo 3 > /proc/sys/vm/drop_caches) y luego se ejecuta el conjunto de datos de prueba. A continuación, el conjunto de datos ref se ejecuta tres veces. El valor medio de los tres resultados de la prueba ref se utiliza como resultado final. Para reducir las fluctuaciones de rendimiento causadas por la migración de CPU o el cambio de contexto, los procesos que se ejecutan en el conjunto de datos de prueba y el conjunto de datos ref se vinculan a un núcleo de CPU mediante la herramienta de afinidad de CPU. Para la prueba de tiempo de compilación, este método utiliza el hilo 1 para construir el programa de prueba y comparar los elementos de prueba que se han compilado durante mucho tiempo. El tiempo de compilación no incluye el tiempo de ejecución del enlazador. Solo incluye el momento en que se generan todos los archivos de origen de todos los programas de prueba.

Comparación del rendimiento de la compilación

El proceso de compilación del CCG es el siguiente: lea el archivo de origen, preprocese el archivo de origen, conviértalo en un IR, optimice y genere un archivo ensamblador. A continuación, el ensamblador genera un archivo objeto. Clang y LLVM no dependen de compiladores independientes, sino que integran compiladores auto-implementados en el backend. El proceso de generación de archivos ensamblados se omite en el proceso de generación de archivos objeto. El archivo objeto se genera directamente desde el IR. Además, en comparación con el GCC IR, la estructura de datos de LLVM IR es más concisa. Ocupa menos memoria durante la compilación y admite un recorrido más rápido. Por lo tanto, Clang y LLVM son ventajosos en términos de tiempo de compilación, lo que se demuestra con los datos obtenidos de la compilación de ESPECIFICACIONES, como se muestra en la figura a continuación. Clang reduce el tiempo de compilación de un solo hilo entre un 5% y un 10% en comparación con GCC. Por lo tanto, Clang ofrece más ventajas para la construcción de grandes proyectos.

Comparación de las ESPECIFICACIONES tiempo de compilación

Comparación de Rendimiento en la Ejecución de

la Mayoría de la nube de cargas de trabajo que requieren que las aplicaciones se pueden ejecutar en diferentes grupos. Al crear estas aplicaciones, no especifique parámetros relacionados con la máquina. Para adaptarse a la iteración rápida causada por los cambios en la demanda, las cargas de trabajo fuera de las instalaciones también deben ser depurables. Por lo tanto, aparte de algunas bibliotecas estables y comunes que permiten altos niveles de optimización de compilación, la carga de trabajo en sí tiene un bajo nivel de compilación y optimización (O2 o inferior). Para cumplir con este requisito, este documento compara el rendimiento de diferentes compiladores en los niveles de optimización de O2 y O3 para programas de velocidad INT, como se muestra en la siguiente figura:

Comparación de rendimiento de la ESPECIFICACIÓN CPU2017 INT Speed

GCC tiene una ventaja de rendimiento del 1% al 4% sobre Clang y LLVM para la mayoría de los programas en los niveles de O2 y O3, y en promedio tiene una ventaja de rendimiento de aproximadamente el 3% para la ESPECIFICACIÓN CPU2017 INT Speed. En términos de 600.perlbench_s y 602.gcc_s / O2, GCC tiene una gran ventaja de rendimiento (más del 10%). Estos dos elementos de prueba no tienen puntos de acceso sobresalientes y pueden reflejar el efecto de optimización integral del compilador. Los resultados de las pruebas muestran que GCC siempre es ventajoso en la optimización del rendimiento. Sin embargo, para dos programas relacionados con la IA, incluido el 631.deepsjeng_s y 641.leela_s, que se agregan recientemente a la prueba de ESPECIFICACIONES, Clang y LLVM mejoran el rendimiento en más de un 3% en comparación con GCC. Esto también refleja el rápido progreso de LLVM en términos de optimización. Para el 625. optimización de O2 x264_s, LLVM mejora el rendimiento en un 40% porque el punto de acceso del caso cumple con las reglas vectorizadas. Pero Clang y LLVM optimizan los vectores a nivel de O2, mientras que GCC optimiza los vectores a nivel de O3. A excepción de los programas vectorizados, GCC no mejora en gran medida el rendimiento a nivel de O3 en comparación con el nivel de O2. En otras palabras, los programas no son sensibles a la optimización de GCC O3. Por el contrario, Clang y LLVM mejoran significativamente el rendimiento de algunos programas (como 600. perlbench_s y 602. gcc_s) a nivel de O3.

Los programas HPC, como la velocidad FP, generalmente se ejecutan en servidores de gama alta. Tienen algoritmos centrales estables, altos requisitos de vectorización y paralelismo relacionados con el rendimiento, y permiten altos niveles de optimización (O3 o superior). Por lo tanto, este documento compara el rendimiento en el nivel de optimización O3 + march = native (skylake-avx512), como se muestra a continuación:

comparación de Rendimiento de la ESPECIFICACIÓN CPU2017 FP de Velocidad

Para los dos programas de PF, GCC también puede mejorar el rendimiento de alrededor de un 3%. Clang y LLVM son conservadores en la optimización de bucles y, por lo tanto, no son ventajosos en el rendimiento. Sin embargo, el subproyecto Polly de Clang y LLVM proporciona un optimizador de localidad de datos y bucle de alto nivel que se ha aplicado ampliamente en aprendizaje automático, computación de alto rendimiento y optimización de computación heterogénea. Creo que Polly puede mejorar en gran medida el rendimiento de los programas que contienen bucles de punto de acceso que cumplen con las reglas de vectorización y paralelismo. También analizaré el rendimiento de Polly en una serie de puntos de referencia y cargas de trabajo.

Observaciones finales

De las pruebas de evaluación comparativa anteriores, podemos ver que Clang ofrece más ventajas para la construcción de grandes proyectos, mientras que GCC siempre es ventajoso en la optimización del rendimiento. El bla depende de su aplicación específica

Además de la comparación de rendimiento, me gustaría compartir las ventajas y desventajas de GCC y Clang y LLVM:

Ventajas de GCC

  • GCC admite lenguajes más tradicionales que Clang y LLVM, como Ada, Fortran y Go.
  • GCC soporta arquitecturas menos populares y soporta RISC-V antes que Clang y LLVM.
  • GCC admite más extensiones de idioma y más funciones de lenguaje ensamblador que Clang y LLVM. GCC sigue siendo la única opción para compilar el núcleo Linux. Aunque la investigación sobre la compilación del núcleo mediante el uso de Clang y LLVM también se informa en la industria, el núcleo no se puede compilar sin modificar el código fuente y los parámetros de compilación.

Ventajas de Clang y LLVM

  • Los lenguajes emergentes utilizan los frameworks LLVM, como Swift, Rust, Julia y Ruby.
  • Clang y LLVM cumplen con los estándares C y C ++ más estrictamente que GCC. GNU Inline y otros problemas durante la actualización de GCC no ocurren.
  • Clang también admite algunas extensiones, como atributos para la comprobación de seguridad de subprocesos.
  • Clang proporciona herramientas útiles adicionales, como scan-build y clang static analyzer para análisis estático, clang-format y clang-tidy para análisis de sintaxis, así como el complemento de editor Clangd.
  • Clang proporciona información de diagnóstico más precisa y amigable, y resalta mensajes de error, líneas de error, indicaciones de líneas de error y sugerencias de reparación. Clang considera la información de diagnóstico como una característica. La información diagnóstica comenzó a mejorarse solo a partir de GCC 5.0, y maduró en GCC 8.

(Artículo original de Ma jun Jun)

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *