Copyright
Copyright © José Luis Lara Carrascal 2012-2024
Sumario
Introducción
Instalación
Configurar el sistema para el uso de Clang
Optimizaciones de CPU para Clang
Niveles de optimización soportados por Clang
Optimizaciones adicionales para Clang
LLD - El enlazador dinámico de LLVM
Libc++ - La librería estándar de C++ de LLVM
Comparativa de resultados de optimización entre Clang y GCC
Enlaces
Introducción
Clang es un software creado para proveer al compilador LLVM de una interfaz para poder compilar código escrito en C, C++, Objective C y Objective C++. Compatible con GCC,
es más rápido y utiliza menos memoria que este
último, aunque no soporta de momento, todas las
características de GCC. En este manual trataremos su instalación y la de LLVM, además de explicar la forma de configurar el sistema para su uso, y las diferencias respecto a GCC,
en lo que concierne a las optimizaciones de procesador. A partir de la
publicación de este manual, todos los manuales de la web que
sean compatibles con Clang,
incluirán la correspondiente información para su uso,
tomando como referencia la instalación tratada en este manual.
Desde el 2 de mayo de 2018, el manual se ha actualizado a una
instalación en un sistema de 64 bits multiarquitectura.
Instalación
Dependencias
Herramientas de Compilación
Entre paréntesis la versión con la que se ha compilado Clang para la elaboración de este documento.
* GCC - (14.2.0) o Clang - (19.1.3)
* CMake - (3.31.0)
* Ninja - (1.12.1)
* Pkg-config - (0.29.2)
Librerías de Desarrollo
* GNU Binutils - (2.43.1)
* Elfutils - (0.192)
* Libffi - (3.4.6)
* Libxml2 - (2.11.9)
* Libzstd - (1.5.6)
* Ncurses - (6.5)
* SPIRV-Tools - (2024.3)
* Zlib - (1.3.1)
Intérpretes de Lenguaje de Programación
* Perl - (5.40.0)
* Python - (3.13.0)
Pygments - (2.18.0)
PyYAML - (6.0.2)
Aplicaciones
* Sphinx - (8.1.3)
Descarga
llvm-19.1.4.tar.lz
Firma Digital
llvm-19.1.4.tar.lz.asc
Verificar la firma digital del paquete
$ gpg --import manualinux.asc
$ gpg --verify llvm-19.1.4.tar.lz.asc llvm-19.1.4.tar.lz
|
Optimizaciones
$ export {C,CXX}FLAGS='-O3 -march=znver3 -mtune=znver3'
|
Donde pone znver3 se indica el procesador respectivo de cada sistema seleccionándolo de la siguiente tabla: |
Nota informativa sobre las optimizaciones para GCC
|
* La opción '-march=' establece el procesador mínimo con el que funcionará el programa compilado, la opción '-mtune=' el procesador específico para el que será optimizado.
* Los valores separados por comas, son equivalentes, es decir, que lo mismo da poner '-march=k8' que '-march=athlon64'.
* En versiones de GCC 3.2 e inferiores se utiliza la opción '-mcpu=' en lugar de '-mtune='.
|
Nota informativa sobre las optimizaciones para Clang
|
* La opción '-mtune=' está soportada a partir de la versión 3.4 de Clang.
* Los valores de color azul no son compatibles con Clang.
* Las filas con el fondo de color amarillo son valores exclusivos de Clang y, por lo tanto, no son aplicables con GCC.
|
Valores |
CPU |
Genéricos |
generic |
Produce un código
binario optimizado para la mayor parte de procesadores existentes.
Utilizar este valor si no sabemos el nombre del procesador que tenemos
en nuestro equipo. Este valor sólo es aplicable en la
opción '-mtune=', si utilizamos GCC. Esta opción está disponible a partir de GCC 4.2. |
native |
Produce un código
binario optimizado para el procesador que tengamos en nuestro sistema,
siendo éste detectado utilizando la instrucción cpuid.
Procesadores antiguos pueden no ser detectados utilizando este valor.
Esta opción está disponible a partir de GCC 4.2. |
x86-64 |
Procesador genérico con extensiones 64-bit. Esta opción está disponible a partir de GCC 8 y Clang 1.9. |
x86-64-v2 |
Procesador
genérico con con soporte de instrucciones X86-64 (MMX, SSE,
SSE2, LAHFSAHF, POPCNT, SSE3, SSE4.1, SSE4.2, SSSE3) y extensiones
64-bit. Esta opción está disponible a partir de GCC 11 y Clang 12. |
x86-64-v3 |
Procesador
genérico con con soporte de instrucciones X86-64 (MMX, SSE,
SSE2, LAHFSAHF, POPCNT, SSE3, SSE4.1, SSE4.2, SSSE3, AVX, AVX2, F16C,
FMA, LZCNT, MOVBE, XSAVE, XSAVEC, FMA4) y extensiones 64-bit. Esta
opción está disponible a partir de GCC 11 y Clang 12. |
x86-64-v4 |
Procesador
genérico con con soporte de instrucciones X86-64 (MMX, SSE,
SSE2, LAHFSAHF, POPCNT, SSE3, SSE4.1, SSE4.2, SSSE3, AVX, AVX2, F16C,
FMA, LZCNT, MOVBE, XSAVE, XSAVEC, AVX512*, FMA4) y extensiones 64-bit.
Esta opción está disponible a partir de GCC 11 y Clang 12. |
Intel |
alderlake |
Intel Alderlake con
soporte de instrucciones x86-64 (MOVBE, MMX, SSE, SSE2, SSE3, SSSE3,
SSE4.1, SSE4.2, POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND,
FMA, BMI, BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC,
XSAVES, AVX512F, CLWB, AVX512VL, AVX512BW, AVX512DQ, AVX512CD,
AVX512VNNI, AVX512BF16, MOVDIRI, MOVDIR64B, AVX512VP2INTERSECT, ENQCMD,
CLDEMOTE, PTWRITE, WAITPKG, SERIALIZE, TSXLDTRK, UINTR, AMX-BF16,
AMX-TILE, AMX-INT8, AVX-VNNI) y extensiones 64-bit. Esta opción
está disponible a partir de GCC 11 y Clang 12. |
arrowlake |
Intel Arrow Lake con
soporte de instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1,
SSE4.2, POPCNT, AES, PREFETCHW, PCLMUL, RDRND, XSAVE, XSAVEC, XSAVES,
XSAVEOPT, FSGSBASE, PTWRITE, RDPID, SGX, GFNI-SSE, CLWB, MOVDIRI,
MOVDIR64B, CLDEMOTE, WAITPKG, ADCX, AVX, AVX2, BMI, BMI2, F16C, FMA,
LZCNT, PCONFIG, PKU, VAES, VPCLMULQDQ, SERIALIZE, HRESET, KL, WIDEKL,
AVX-VNNI, UINTR, AVXIFMA, AVXVNNIINT8, AVXNECONVERT, CMPCCXADD y
extensiones 64-bit. Esta opción está disponible a partir
de GCC 14. |
arrowlake-s |
Intel Arrow Lake S con
soporte de instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1,
SSE4.2, POPCNT, AES, PREFETCHW, PCLMUL, RDRND, XSAVE, XSAVEC, XSAVES,
XSAVEOPT, FSGSBASE, PTWRITE, RDPID, SGX, GFNI-SSE, CLWB, MOVDIRI,
MOVDIR64B, CLDEMOTE, WAITPKG, ADCX, AVX, AVX2, BMI, BMI2, F16C, FMA,
LZCNT, PCONFIG, PKU, VAES, VPCLMULQDQ, SERIALIZE, HRESET, KL, WIDEKL,
AVX-VNNI, UINTR, AVXIFMA, AVXVNNIINT8, AVXNECONVERT, CMPCCXADD,
AVXVNNIINT16, SHA512, SM3, SM4 y extensiones 64-bit. Esta opción
está disponible a partir de GCC 14. |
atom |
Intel Atom con soporte de
instrucciones MMX, SSE, SSE2, SSE3, SSSE3 y extensiones
64-bit. Esta opción está disponible desde GCC 4.6, hasta GCC 4.8. A partir de GCC 4.9 se utiliza la definición bonnell. |
bonnell |
Intel Bonnell con soporte
de instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3 y extensiones
64-bit. Esta opción está disponible a partir de GCC 4.9. |
broadwell |
Intel Broadwell con
soporte de instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1,
SSE4.2, POPCNT, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI,
BMI2, F16C, RDSEED, ADCX, PREFETCHW y extensiones 64-bit. Esta
opción está disponible a partir de GCC 4.9 y Clang 3.6. |
cannonlake |
Intel Cannonlake Server
con soporte de instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3,
SSE4.1, SSE4.2, POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND,
FMA, BMI, BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC,
XSAVES, AVX512F, AVX512VL, AVX512BW, AVX512DQ, AVX512CD, AVX512VBMI,
AVX512IFMA, SHA, UMIP y extensiones 64-bit. Esta opción
está disponible a partir de GCC 8 y Clang 3.9. |
cascadelake |
Intel Cascadelake con
soporte de instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1,
SSE4.2, POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI,
BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC, XSAVES,
AVX512F, CLWB, AVX512VL, AVX512BW, AVX512DQ, AVX512CD, AVX512VNNI y
extensiones 64-bit. Esta opción está disponible a
partir de GCC 9 y Clang 8. |
clearwaterforest |
Intel
Clearwater Forest con soporte de instrucciones MOVBE, MMX, SSE, SSE2,
SSE3, SSSE3, SSE4.1, SSE4.2, POPCNT, AES, PREFETCHW, PCLMUL, RDRND,
XSAVE, XSAVEC, XSAVES, XSAVEOPT, FSGSBASE, PTWRITE, RDPID, SGX,
GFNI-SSE, CLWB, MOVDIRI, MOVDIR64B, CLDEMOTE, WAITPKG, ADCX, AVX, AVX2,
BMI, BMI2, F16C, FMA, LZCNT, PCONFIG, PKU, VAES, VPCLMULQDQ, SERIALIZE,
HRESET, KL, WIDEKL, AVX-VNNI, ENQCMD, UINTR, AVXIFMA, AVXVNNIINT8,
AVXNECONVERT, CMPCCXADD, AVXVNNIINT16, SHA512, SM3, SM4, USER_MSR,
PREFETCHI y extensiones 64-bit. Esta opción está
disponible a partir de GCC 14 y Clang 18. |
cooperlake |
Intel
Cooper Lake con soporte de instrucciones MOVBE, MMX, SSE, SSE2, SSE3,
SSSE3, SSE4.1, SSE4.2, POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE,
RDRND, FMA, BMI, BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT,
XSAVEC, XSAVES, AVX512F, CLWB, AVX512VL, AVX512BW, AVX512DQ, AVX512CD,
AVX512VNNI, AVX512BF16 y extensiones 64-bit. Esta opción
está disponible a partir de GCC 10 y Clang 9. |
core2 |
Intel Core2
con soporte de instrucciones MMX, SSE, SSE2, SSE3, SSSE3 y
extensiones 64-bit. Esta opción está disponible a partir
de GCC 4.3. |
core-avx2 |
Intel Core (Haswell). Esta opción está disponible desde GCC 4.6, hasta GCC 4.8. A partir de GCC 4.9 se utiliza la definición haswell. |
core-avx-i |
Intel Core (ivyBridge)
con soporte de instrucciones MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1,
SSE4.2, AVX, AES, PCLMUL, FSGSBASE, RDRND, F16C y extensiones
64-bit. Esta opción está disponible desde GCC 4.6, hasta GCC 4.8. A partir de GCC 4.9 se utiliza la definición ivybridge. |
corei7 |
Intel Core i7
con soporte de instrucciones MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1 y
SSE4.2 y extensiones 64-bit. Soporta también los procesadores
Intel Core i3 e i5. Esta opción está disponible
desde GCC 4.6, hasta GCC 4.8. A partir de GCC 4.9 se utiliza la definición nehalem. |
corei7-avx |
Intel Core i7 con
soporte de instrucciones MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2,
AVX, AES y PCLMUL y extensiones 64-bit. Soporta también los
procesadores Intel Core i3 e i5. Esta opción está
disponible desde GCC 4.6, hasta GCC 4.8. A partir de GCC 4.9 se utiliza la definición sandybridge. |
emeraldrapids |
Intel Emerald Rapids. Esta opción está disponible a partir de GCC 13 y Clang 16. |
goldmont |
Intel Goldmont con soporte
de instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2,
POPCNT, AES, PCLMUL, RDRND, XSAVE, XSAVEOPT, FSGSBASE y extensiones
64-bit. Esta opción está disponible a partir de GCC 9 y Clang 5. |
goldmont-plus |
Intel Goldmont Plus con
soporte de instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1,
SSE4.2, POPCNT, AES, PCLMUL, RDRND, XSAVE, XSAVEOPT, FSGSBASE, PTWRITE,
RDPID, SGX, UMIP y extensiones 64-bit. Esta opción está
disponible a partir de GCC 9 y Clang 7. |
grandridge |
Intel Grand Ridge con
soporte de instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1,
SSE4.2, POPCNT, AES, PREFETCHW, PCLMUL, RDRND, XSAVE, XSAVEC, XSAVES,
XSAVEOPT, FSGSBASE, PTWRITE, RDPID, SGX, GFNI-SSE, CLWB, MOVDIRI,
MOVDIR64B, CLDEMOTE, WAITPKG, ADCX, AVX, AVX2, BMI, BMI2, F16C, FMA,
LZCNT, PCONFIG, PKU, VAES, VPCLMULQDQ, SERIALIZE, HRESET, KL, WIDEKL,
AVX-VNNI, AVXIFMA, AVXVNNIINT8, AVXNECONVERT, CMPCCXADD, RAOINT y
extensiones 64-bit. Esta opción está disponible a partir
de GCC 13 y Clang 16. |
graniterapids |
Intel Grand Ridge con
soporte de instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1,
SSE4.2, POPCNT, CX16, SAHF, FXSR, AVX, XSAVE, PCLMUL, FSGSBASE, RDRND,
F16C, AVX2, BMI, BMI2, LZCNT, FMA, MOVBE, HLE, RDSEED, ADCX, PREFETCHW,
AES, CLFLUSHOPT, XSAVEC, XSAVES, SGX, AVX512F, AVX512VL, AVX512BW,
AVX512DQ, AVX512CD, PKU, AVX512VBMI, AVX512IFMA, SHA, AVX512VNNI, GFNI,
VAES, AVX512VBMI2, VPCLMULQDQ, AVX512BITALG, RDPID, AVX512VPOPCNTDQ,
PCONFIG, WBNOINVD, CLWB, MOVDIRI, MOVDIR64B, AVX512VP2INTERSECT,
ENQCMD, CLDEMOTE, PTWRITE, WAITPKG, SERIALIZE, TSXLDTRK, UINTR,
AMX-BF16, AMX-TILE, AMX-INT8, AVX-VNNI, AVX512-FP16, AVX512BF16,
AMX-FP16, PREFETCHI y extensiones 64-bit. Esta opción
está disponible a partir de GCC 13 y Clang 16. |
graniterapids-d |
Intel Granite Rapids D con
soporte de instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1,
SSE4.2, POPCNT, CX16, SAHF, FXSR, AVX, XSAVE, PCLMUL, FSGSBASE, RDRND,
F16C, AVX2, BMI, BMI2, LZCNT, FMA, MOVBE, HLE, RDSEED, ADCX, PREFETCHW,
AES, CLFLUSHOPT, XSAVEC, XSAVES, SGX, AVX512F, AVX512VL, AVX512BW,
AVX512DQ, AVX512CD, PKU, AVX512VBMI, AVX512IFMA, SHA, AVX512VNNI, GFNI,
VAES, AVX512VBMI2, VPCLMULQDQ, AVX512BITALG, RDPID, AVX512VPOPCNTDQ,
PCONFIG, WBNOINVD, CLWB, MOVDIRI, MOVDIR64B, ENQCMD, CLDEMOTE, PTWRITE,
WAITPKG, SERIALIZE, TSXLDTRK, UINTR, AMX-BF16, AMX-TILE, AMX-INT8,
AVX-VNNI, AVX512FP16, AVX512BF16, AMX-FP16, PREFETCHI, AMX-COMPLEX y
extensiones 64-bit. Esta opción está disponible a partir
de GCC 14 y Clang 17. |
haswell |
Intel Haswell con soporte
de instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2,
POPCNT, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI, BMI2, F16C y
extensiones 64-bit. Esta opción está disponible a
partir de GCC 4.9. |
i386 |
Intel i386.
|
i486 |
Intel i486. |
i586, pentium |
Intel Pentium sin soporte de instrucciones MMX. |
i686 |
Produce un código
binario optimizado para la mayor parte de procesadores compatibles con
la serie 80686 de Intel. Todos los actuales lo son. |
icelake-client |
Intel Icelake Client con
soporte de instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1,
SSE4.2, POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI,
BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC, XSAVES,
AVX512F, AVX512VL, AVX512BW, AVX512DQ, AVX512CD, AVX512VBMI,
AVX512IFMA, SHA, CLWB, UMIP, RDPID, GFNI, AVX512VBMI2, AVX512VPOPCNTDQ,
AVX512BITALG, AVX512VNNI, VPCLMULQDQ, VAES y extensiones
64-bit. Esta opción está disponible a partir de GCC 8 y Clang 7. |
icelake-server |
Intel Icelake Server con
soporte de instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1,
SSE4.2, POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI,
BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC, XSAVES,
AVX512F, AVX512VL, AVX512BW, AVX512DQ, AVX512CD, AVX512VBMI,
AVX512IFMA, SHA, CLWB, UMIP, RDPID, GFNI, AVX512VBMI2, AVX512VPOPCNTDQ,
AVX512BITALG, AVX512VNNI, VPCLMULQDQ, VAES, PCONFIG, WBNOINVD y
extensiones 64-bit. Esta opción está disponible a
partir de GCC 8 y Clang 7. |
intel |
Intel Haswell y
Silvermont. Este valor sólo es aplicable en la
opción '-mtune='. Esta opción está disponible
a partir de GCC 4.9. |
ivybridge |
Intel Ivy Bridge con
soporte de instrucciones MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2,
POPCNT, AVX, AES, PCLMUL, FSGSBASE, RDRND, F16C y extensiones
64-bit. Esta opción está disponible a partir de GCC 4.9. |
knl |
Intel Knights Landing con
soporte de instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1,
SSE4.2, POPCNT, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI,
BMI2, F16C, RDSEED, ADCX, PREFETCHW, AVX512F, AVX512PF, AVX512ER y
extensiones 64-bit. Esta opción está disponible a
partir de GCC 5 y Clang 3.4. |
knm |
Intel Knights Mill con
soporte de instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1,
SSE4.2, POPCNT, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI,
BMI2, F16C, RDSEED, ADCX, PREFETCHW, AVX512F, AVX512PF, AVX512ER,
AVX512CD, AVX5124VNNIW, AVX5124FMAPS, AVX512VPOPCNTDQ y extensiones
64-bit. Esta opción está disponible a partir de GCC 8 y Clang 6. |
lakemont |
Intel Quark Lakemont MCU, basado en el procesador Intel Pentium. Esta opción está disponible a partir de GCC 6 y Clang 3.9. |
lunarlake |
Intel Lunar Lake. Esta opción está disponible a partir de GCC 14 y es equivalente a la opción arrowlake-s. |
meteorlake |
Intel Meteor Lake. Esta opción está disponible a partir de GCC 13 y Clang 16. |
nehalem |
Intel Nehalem con soporte
de instrucciones MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, POPCNT y
extensiones 64-bit. Esta opción está disponible a
partir de GCC 4.9. |
nocona |
Versión mejorada de Intel Pentium4 con soporte de instrucciones MMX, SSE, SSE2, SSE3 y extensiones 64-bit. |
pantherlake |
Intel
Panther Lake con soporte de instrucciones MOVBE, MMX, SSE, SSE2, SSE3,
SSSE3, SSE4.1, SSE4.2, POPCNT, AES, PREFETCHW, PCLMUL, RDRND, XSAVE,
XSAVEC, XSAVES, XSAVEOPT, FSGSBASE, PTWRITE, RDPID, SGX, GFNI-SSE,
CLWB, MOVDIRI, MOVDIR64B, CLDEMOTE, WAITPKG, ADCX, AVX, AVX2, BMI,
BMI2, F16C, FMA, LZCNT, PCONFIG, PKU, VAES, VPCLMULQDQ, SERIALIZE,
HRESET, KL, WIDEKL, AVX-VNNI, UINTR, AVXIFMA, AVXVNNIINT8,
AVXNECONVERT, CMPCCXADD, AVXVNNIINT16, SHA512, SM3, SM4, PREFETCHI y
extensiones 64-bit. Esta opción está disponible a partir
de GCC 14 y Clang 18. |
penryn |
Intel Penryn con soporte de instrucciones MMX, SSE, SSE2, SSE3, SSSE3 y SSE4.1. |
pentiumpro |
Intel PentiumPro. |
pentium2 |
Intel Pentium2 basado en PentiumPro con soporte de instrucciones MMX. |
pentium3, pentium3m |
Intel Pentium3 basado en PentiumPro con soporte de instrucciones MMX y SSE. |
pentium4, pentium4m |
Intel Pentium4 con soporte de instrucciones MMX, SSE y SSE2. |
pentium-m |
Versión de bajo
consumo de Intel Pentium3 con soporte de instrucciones MMX, SSE y SSE2.
Utilizado por los portátiles Centrino. |
pentium-mmx |
Intel PentiumMMX basado en Pentium con soporte de instrucciones MMX. |
prescott |
Versión mejorada de Intel Pentium4 con soporte de instrucciones MMX, SSE, SSE2 y SSE3. |
raptorlake |
Intel Raptor Lake. Esta opción está disponible a partir de GCC 13 y Clang 16. |
rocketlake |
Intel Rocket Lake con
soporte de instrucciones x86-64 (MOVBE, MMX, SSE, SSE2, SSE3, SSSE3,
SSE4.1, SSE4.2, POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND,
FMA, BMI, BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC,
XSAVES, AVX512F, AVX512VL, AVX512BW, AVX512DQ, AVX512CD, AVX512VBMI,
AVX512IFMA, SHA, CLWB, UMIP, RDPID, GFNI, AVX512VBMI2, AVX512VPOPCNTDQ,
AVX512BITALG, AVX512VNNI, VPCLMULQDQ, VAES) y extensiones 64-bit. Esta
opción está disponible a partir de GCC 11 y Clang 13. |
sandybridge |
Intel Sandy Bridge con
soporte de instrucciones MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2,
POPCNT, AVX, AES, PCLMUL y extensiones 64-bit. Esta opción
está disponible a partir de GCC 4.9 y Clang 3.6. |
sapphirerapids |
Intel Sapphire Rapids
con soporte de instrucciones x86-64 (MOVBE, MMX, SSE, SSE2, SSE3,
SSSE3, SSE4.1, SSE4.2, POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE,
RDRND, FMA, BMI, BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT,
XSAVEC, XSAVES, AVX512F, CLWB, AVX512VL, AVX512BW, AVX512DQ, AVX512CD,
AVX512VNNI, AVX512BF16, MOVDIRI, MOVDIR64B, AVX512VP2INTERSECT, ENQCMD,
CLDEMOTE, PTWRITE, WAITPKG, SERIALIZE, TSXLDTRK, UINTR, AMX-BF16,
AMX-TILE, AMX-INT8, AVX-VNNI) y extensiones 64-bit. Esta opción
está disponible a partir de GCC 11 y Clang 12. |
silvermont |
Intel Silvermont con
soporte de instrucciones MOVBE, MMX, SSE, MOVBE, MMX, SSE, SSE2, SSE3,
SSSE3, SSE4.1, SSE4.2, POPCNT, AES, PCLMU, RDRND y extensiones
64-bit. Esta opción está disponible a partir de GCC 4.9 y Clang 3.6. |
sierraforest |
Intel Sierra Forest con
soporte de instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1,
SSE4.2, POPCNT, AES, PREFETCHW, PCLMUL, RDRND, XSAVE, XSAVEC, XSAVES,
XSAVEOPT, FSGSBASE, PTWRITE, RDPID, SGX, GFNI-SSE, CLWB, MOVDIRI,
MOVDIR64B, CLDEMOTE, WAITPKG, ADCX, AVX, AVX2, BMI, BMI2, F16C, FMA,
LZCNT, PCONFIG, PKU, VAES, VPCLMULQDQ, SERIALIZE, HRESET, KL, WIDEKL,
AVX-VNNI, AVXIFMA, AVXVNNIINT8, AVXNECONVERT, CMPCCXADD y extensiones
64-bit. Esta opción está disponible a partir de GCC 13 y Clang 16. |
skylake |
Intel Skylake
con soporte de instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3,
SSE4.1, SSE4.2, POPCNT, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA,
BMI, BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC, XSAVES y
extensiones 64-bit. Esta opción está disponible a partir
de GCC 6 y Clang 3.6. |
skylake-avx512 |
Intel Skylake Server
con soporte de instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3,
SSE4.1, SSE4.2, POPCNT, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA,
BMI, BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC, XSAVES,
AVX512F, AVX512VL, AVX512BW, AVX512DQ, AVX512CD y extensiones 64-bit.
Esta opción está disponible a partir de GCC 6 y Clang 3.9. |
tigerlake |
Intel
Tiger Lake con soporte de instrucciones OVBE, MMX, SSE, SSE2, SSE3,
SSSE3, SSE4.1, SSE4.2, POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE,
RDRND, FMA, BMI, BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT,
XSAVEC, XSAVES, AVX512F, AVX512VL, AVX512BW, AVX512DQ, AVX512CD,
AVX512VBMI, AVX512IFMA, SHA, CLWB, UMIP, RDPID, GFNI, AVX512VBMI2,
AVX512VPOPCNTDQ, AVX512BITALG, AVX512VNNI, VPCLMULQDQ, VAES, PCONFIG,
WBNOINVD, MOVDIRI, MOVDIR64B, AVX512VP2INTERSECT y extensiones 64-bit.
Esta opción está disponible a partir de GCC 10 y Clang 10. |
tremont |
Intel Tremont con soporte
de instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2,
POPCNT, AES, PCLMUL, RDRND, XSAVE, XSAVEOPT, FSGSBASE, PTWRITE, RDPID,
SGX, UMIP, GFNI-SSE, CLWB, ENCLV y extensiones 64-bit. Esta
opción está disponible a partir de GCC 9 y Clang 7. |
westmere |
Intel Westmere con soporte
de instrucciones MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, POPCNT,
AES, PCLMUL y extensiones 64-bit. Esta opción está
disponible a partir de GCC 4.9. |
yonah |
Procesadores basados en la microarquitectura de Pentium M, con soporte de instrucciones MMX, SSE, SSE2 y SSE3. |
AMD |
amdfam10, barcelona |
Procesadores basados en
AMD Family 10h core con soporte de instrucciones x86-64 (MMX, SSE,
SSE2, SSE3, SSE4A, 3DNow!, enhanced 3DNow!, ABM y extensiones
64-bit). Esta opción está disponible a partir de GCC 4.3. La definición barcelona está disponible a partir de Clang 3.6. |
athlon, athlon-tbird |
AMD Athlon con soporte de instrucciones MMX, 3DNow!, enhanced 3DNow! y SSE prefetch. |
athlon4, athlon-xp, athlon-mp |
Versiones mejoradas de AMD Athlon con soporte de instrucciones MMX, 3DNow!, enhanced 3DNow! y full SSE. |
bdver1 |
Procesadores basados en
AMD Family 15h core con soporte de instrucciones x86-64 (FMA4, AVX,
XOP, LWP, AES, PCL_MUL, CX16, MMX, SSE, SSE2, SSE3, SSE4A, SSSE3,
SSE4.1, SSE4.2, ABM y extensiones 64-bit). Esta opción
está disponible a partir de GCC 4.7. |
bdver2 |
Procesadores basados en
AMD Family 15h core con soporte de instrucciones x86-64 (BMI, TBM,
F16C, FMA, LWP, AVX, XOP, LWP, AES, PCL_MUL, CX16, MMX, SSE, SSE2,
SSE3, SSE4A, SSSE3, SSE4.1, SSE4.2, ABM y extensiones
64-bit). Esta opción está disponible a partir de GCC 4.7. |
bdver3 |
Procesadores basados en
AMD Family 15h core con soporte de instrucciones x86-64 (FMA4, AVX,
XOP, LWP, AES, PCL_MUL, CX16, MMX, SSE, SSE2, SSE3, SSE4A, SSSE3,
SSE4.1, SSE4.2, ABM y extensiones 64-bit). Esta opción
está disponible a partir de GCC 4.8 y Clang 3.4. |
bdver4 |
Procesadores basados en
AMD Family 15h core con soporte de instrucciones x86-64 (BMI, BMI2,
TBM, F16C, FMA, FMA4, FSGSBASE, AVX, AVX2, XOP, LWP, AES, PCL_MUL,
CX16, MOVBE, MMX, SSE, SSE2, SSE3, SSE4A, SSSE3, SSE4.1, SSE4.2, ABM y
extensiones 64-bit). Esta opción está disponible a partir
de GCC 4.9 y Clang 3.5. |
btver1 |
Procesadores basados en
AMD Family 14h core con soporte de instrucciones x86-64 (MMX, SSE,
SSE2, SSE3, SSE4A, CX16, ABM y extensiones 64-bit). Esta
opción está disponible a partir de GCC 4.6. |
btver2 |
Procesadores basados en
AMD Family 16h core con soporte de instrucciones x86-64 (MOVBE, F16C,
BMI, AVX, PCL_MUL, AES, SSE4.2, SSE4.1, CX16, ABM, SSE4A, SSSE3, SSE3,
SSE2, SSE, MMX y extensiones 64-bit). Esta opción
está disponible a partir de GCC 4.8. |
geode |
AMD integrado con soporte de instrucciones MMX y 3DNow!. Esta opción está disponible a partir de GCC 4.3. |
k6 |
AMD K6 con soporte de instrucciones MMX. |
k6-2, k6-3 |
Versiones mejoradas de AMD K6 con soporte de instrucciones MMX y 3DNow!. |
k8, opteron, athlon64, athlon-fx |
Procesadores basados en
AMD K8 core con soporte de instrucciones x86-64 (MMX, SSE, SSE2,
3DNow!, enhanced 3DNow! y extensiones 64-bit). |
k8-sse3, opteron-sse3, athlon64-sse3 |
Versiones mejoradas de AMD
K8 core con soporte de instrucciones SSE3. Esta opción
está disponible a partir de GCC 4.3. |
znver1 |
Procesadores basados en
AMD Family 17h core con soporte de instrucciones x86-64 (BMI, BMI2,
F16C, FMA, FSGSBASE, AVX, AVX2, ADCX, RDSEED, MWAITX, SHA, CLZERO, AES,
PCL_MUL, CX16, MOVBE, MMX, SSE, SSE2, SSE3, SSE4A, SSSE3, SSE4.1,
SSE4.2, ABM, XSAVEC, XSAVES, CLFLUSHOPT, POPCNT y extensiones
64-bit). Esta opción está disponible a partir de GCC 6 y Clang 4. |
znver2 |
Procesadores basados en
AMD Family 17h core con soporte de instrucciones x86-64 (BMI, BMI2,
,CLWB, F16C, FMA, FSGSBASE, AVX, AVX2, ADCX, RDSEED, MWAITX, SHA,
CLZERO, AES, PCL_MUL, CX16, MOVBE, MMX, SSE, SSE2, SSE3, SSE4A, SSSE3,
SSE4.1, SSE4.2, ABM, XSAVEC, XSAVES, CLFLUSHOPT, POPCNT y
extensiones 64-bit). Esta opción está disponible a
partir de GCC 9 y Clang 9. |
znver3 |
Procesadores basados en
AMD Family 19h core con soporte de instrucciones x86-64 (BMI, BMI2,
CLWB, F16C, FMA, FSGSBASE, AVX, AVX2, ADCX, RDSEED, MWAITX, SHA,
CLZERO, AES, PCLMUL, CX16, MOVBE, MMX, SSE, SSE2, SSE3, SSE4A, SSSE3,
SSE4.1, SSE4.2, ABM, XSAVEC, XSAVES, CLFLUSHOPT, POPCNT, RDPID,
WBNOINVD, PKU, VPCLMULQDQ, VAES) y extensiones 64-bit. Esta
opción está disponible a partir de GCC 11 y Clang 12. |
znver4 |
Procesadores basados en
AMD Family 19h core con soporte de instrucciones x86-64 (BMI, BMI2,
CLWB, F16C, FMA, FSGSBASE, AVX, AVX2, ADCX, RDSEED, MWAITX, SHA,
CLZERO, AES, PCLMUL, CX16, MOVBE, MMX, SSE, SSE2, SSE3, SSE4A, SSSE3,
SSE4.1, SSE4.2, ABM, XSAVEC, XSAVES, CLFLUSHOPT, POPCNT, RDPID,
WBNOINVD, PKU, VPCLMULQDQ, VAES, AVX512F, AVX512DQ, AVX512IFMA,
AVX512CD, AVX512BW, AVX512VL, AVX512BF16, AVX512VBMI, AVX512VBMI2,
AVX512VNNI, AVX512BITALG, AVX512VPOPCNTDQ, GFNI) y extensiones 64-bit.
Esta opción está disponible a partir de GCC 12.3 y Clang 16. |
znver5 |
Procesadores basados en
AMD Family 1ah core con soporte de instrucciones x86-64 (BMI, BMI2,
CLWB, F16C, FMA, FSGSBASE, AVX, AVX2, ADCX, RDSEED, MWAITX, SHA,
CLZERO, AES, PCLMUL, CX16, MOVBE, MMX, SSE, SSE2, SSE3, SSE4A, SSSE3,
SSE4.1, SSE4.2, ABM, XSAVEC, XSAVES, CLFLUSHOPT, POPCNT, RDPID,
WBNOINVD, PKU, VPCLMULQDQ, VAES, AVX512F, AVX512DQ, AVX512IFMA,
AVX512CD, AVX512BW, AVX512VL, AVX512BF16, AVX512VBMI, AVX512VBMI2,
AVX512VNNI, AVX512BITALG, AVX512VPOPCNTDQ, GFNI, AVXVNNI, MOVDIRI,
MOVDIR64B, AVX512VP2INTERSECT, PREFETCHI) y extensiones 64-bit. Esta
opción está disponible a partir de GCC 14. |
Optimizaciones adicionales
Optimizaciones adicionales |
GCC |
Graphite
|
$ export {C,CXX}FLAGS+=' -floop-interchange -ftree-loop-distribution -floop-strip-mine -floop-block' |
Clang |
Polly |
$ export {C,CXX}FLAGS+=' -O3 -mllvm -polly -mllvm -polly-vectorizer=stripmine' |
Unified LTO |
LTO >> ThinLTO |
$ export {C,CXX}FLAGS+=' -funified-lto'
$ export LDFLAGS+=' -Wl,--lto=thin' |
ThinLTO >> LTO |
$ export {C,CXX}FLAGS+=' -funified-lto'
$ export LDFLAGS+=' -Wl,--lto=full' |
La aplicación de esta optimización es aplicable, a partir de Clang 17, y sólo es combinable con LLD. En este manual concreto, hay que combinarla con la opción -DLLVM_ENABLE_LTO=ON del proceso de configuración del paquete, si utilizamos la primera opción o, -DLLVM_ENABLE_LTO=Thin, si utilizamos la segunda opción. Lo recomendable siempre, es utilizar la primera opción.
|
Parámetros adicionales para la versión de 32 bits
Optimizaciones de CPU para Intel en sistemas de 64 bits multiarquitectura |
$ export {C,CXX}FLAGS='-O3 -march=i686 -mtune=pentium4' |
Optimizaciones de CPU para AMD en sistemas de 64 bits multiarquitectura |
$ export {C,CXX}FLAGS='-O3 -march=i686 -mtune=athlon-xp' |
Establecer la variable de entorno adecuada para pkg-config en sistemas de 64 bits multiarquitectura |
$ export PKG_CONFIG_PATH=/usr/lib/pkgconfig:/usr/local/lib/pkgconfig:/usr/share/pkgconfig:$PKG_CONFIG_PATH |
Establecer la ruta de búsqueda de directorios de librerías en sistemas de 64 bits multiarquitectura |
$ export LDFLAGS+=' -L/usr/lib -L/usr/local/lib -L/opt/gcc14/lib' |
Establecer
la variable de entorno de arquitectura de procesador requerida en
sistemas de 64 bits multiarquitectura basados en el CLFS |
$ export USE_ARCH=32 |
Establecer la variable de entorno de uso de compilador en modo de 32 bits, en sistemas de 64 bits multiarquitectura |
GCC |
$ export CC="gcc -m32" CXX="g++ -m32"
|
Clang |
$ export CC="clang -m32" CXX="clang++ -m32"
|
Parámetros adicionales para la versión de 64 bits
Establecer la variable de entorno de uso de compilador para Clang |
$ export CC=clang CXX=clang++
|
Parámetros adicionales globales
Parámetros adicionales de eliminación de avisos en el proceso de compilación |
$ export {C,CXX}FLAGS+=' -w' |
Establecer el uso de enlazador dinámico para LLD |
Clang |
$ export LDFLAGS+=' -fuse-ld=lld' |
Optimizaciones complementarias LTO/ThinLTO de LLD |
$ export LDFLAGS+=' -Wl,--lto-aa-pipeline=globals-aa -Wl,--lto-newpm-passes=memcpyopt' |
Optimizaciones complementarias LTO de LLD |
$ export LDFLAGS+=" -Wl,--lto-partitions=$(expr
$(nproc) / 2)" |
Optimizaciones complementarias ThinLTO de LLD |
$ export LDFLAGS+=" -Wl,--thinlto-jobs=$(expr
$(nproc) / 2)" |
Extracción
$ tar axvf llvm-19.1.4.tar.lz
$ cd llvm-19.1.4
|
1) Configuración de la versión de 32 bits
2) Configuración de la versión de 64 bits estática
3) Configuración de la versión de 64 bits compartida
1) Configuración de la versión de 32 bits
La compilación de la versión de 32 bits de LLVM
sólo es necesaria si tenemos pensado compilar la versión
de 32 bits de Mesa con
soporte de LLVM, o somos usuarios de una tarjeta gráfica de AMD
como es mi caso y tenemos que hacer uso del controlador de
gráficos, AMDGPU. A diferencia de GCC, LLVM no compila las
librerías de 32 bits en el mismo proceso de compilación,
en un sistema de 64 bits multiarquitectura.
$ cmake -S llvm -B build32 -DLLVM_ENABLE_PROJECTS="clang;polly" -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/opt/llvm19 -DLLVM_TARGETS_TO_BUILD="X86;AMDGPU;BPF" \
-DBUILD_SHARED_LIBS=ON -DLLVM_ENABLE_RTTI=ON -DLLVM_ENABLE_FFI=ON -DOCAMLFIND=null \
-DCLANG_BUILD_TOOLS=OFF -DLLVM_ENABLE_DUMP=ON -DLLVM_SPIRV_INCLUDE_TESTS=OFF -G Ninja |
Explicación de los comandos
-S llvm -B build32 : Establece el directorio del código fuente y crea de forma automática el directorio de compilación.
-DLLVM_ENABLE_PROJECTS="clang;polly":
Activa la compilación de los proyectos clang y polly,
requeridos para poder compilar el soporte de OpenCL en
Mesa, de las tarjetas gráficas de AMD, utilizando el
controlador Clover de Gallium.
-DCMAKE_BUILD_TYPE=Release : Compila la versión optimizada de LLVM.
-DCMAKE_INSTALL_PREFIX=/opt/llvm19 : Instala LLVM en /opt/llvm19.
-DLLVM_TARGETS_TO_BUILD="X86;AMDGDPU;BPF" : Compila sólo el soporte de la arquitectura de procesador x86, el soporte del controlador de gráficos de código abierto, AMDGPU (requerido para poder compilar Mesa con soporte de las tarjetas gráficas de AMD) y el soporte de BPF, requerido para la compilación del paquete v4l-utils, omitiendo otras como ARM, PowerPC, etc. Esto reduce el tiempo de
compilación y el tamaño del directorio de
instalación del compilador.
-DBUILD_SHARED_LIBS=ON : Compila las librerías compartidas en lugar de las estáticas.
-DLLVM_ENABLE_RTTI=ON : Parámetro requerido para poder compilar Mesa con soporte de LLVM con el sistema de compilación, Meson.
-DLLVM_ENABLE_FFI=ON : Activa el soporte de Libffi, librería de características similares a GMP.
-DOCAMLFIND=null : Al no tener el paquete una opción específica para desactivar la adaptación de LLVM para el lenguaje de programación OCaml, le indicamos una ruta nula al ejecutable ocamlfind,
para poder desactivar el soporte de esta dependencia. Si no tenemos
instalado OCaml en nuestro sistema, esto no hay que añadirlo.
-DCLANG_BUILD_TOOLS=OFF
: Desactiva la compilación del binario ejecutable de Clang, ya
que sólo necesitaremos las librerías para poder compilar
el soporte de OpenCL en Mesa, de las tarjetas gráficas de AMD,
utilizando el controlador Clover de Gallium.
-DLLVM_ENABLE_DUMP=ON : Requerido para poder compilar el soporte del experimental controlador gallium-rusticl de las librerías Mesa.
-DLLVM_SPIRV_INCLUDE_TESTS=OFF : Omite la compilación de los tests de SPIRV-LLVM-Translator.
-G Ninja : Utiliza Ninja en lugar de GNU Make para compilar el paquete (opcional).
Parámetros de configuración opcionales
-DCMAKE_{C,CXX}_COMPILER_LAUNCHER=ccache : Activa el uso de Ccache
en el proceso de compilación. Si tenemos configurado Ccache con
los correspondientes enlaces simbólicos, no es necesario
añadir esta opción. Pero sí tenemos que tener activadas las opciones de Ccache, hash_dir y run_second_cpp,
que vienen activadas por defecto. En la 3ª fase de compilación sí que
es necesario añadirla. Se puede sustituir ccache por buildcache o
sccache, cuyos manuales de instalación se encuentran en esta web.
-DLLVM_ENABLE_LTO=ON|Thin : Activa el uso de la optimización LTO,
tanto con GCC como con Clang, siempre en combinación con el
parámetro anteriormente descrito. Si vamos a utilizar Clang, muy
recomendable hacer uso de ThinLTO en lugar de LTO, estableciendo Thin en lugar de ON,
en el valor de este parámetro, para reducir el tiempo de
compilación del paquete (en versiones inferiores a Clang 17). A
partir de la versión 17 de Clang, es recomendable utilizar la
opción LTO, en combinación con las optimizaciones Unified
LTO, si se utiliza Clang para compilar el paquete.
-DLLVM_ENABLE_LLD=ON
: Este parámetro sólo es necesario si utilizamos la
optimización ThinLTO con Clang, y no tenemos configurado un
directorio caché para LLD en nuestro sistema, cuyo uso hemos
establecido con la correspondiente variable de entorno de uso de
enlazador dinámico para LLD. El proceso de configuración
creará uno en la raíz del directorio de
compilación con el nombre lto.cache
y almacenará en el mismo los archivos objeto que se generen en
el proceso de enlazado, evitando utilizar la memoria física del
sistema, si tenemos montado el directorio /tmp con el sistema de archivos, Tmpfs.
Si se establece LLD como enlazador dinámico, antes del comando
de configuración del paquete, esta opción no será
funcional.
-DLLVM_PARALLEL_LINK_JOBS=$(nproc)
: Establece el número de procesos en paralelo de enlazado (por
defecto es 2), tomando como referencia la información del
número de núcleos de nuestro procesador, proporcionada
por el sistema. Este parámetro sólo es aplicable con Ninja. Si compilamos el paquete con Clang, estableciendo las correspondientes
variables de entorno de LLD de este manual, es recomendable no utilizar esta opción.
-DCMAKE_STRIP=/usr/bin/strip : Sustituye llvm-strip por strip,
en el caso de que compilemos el paquete con Clang. El segundo es
bastante mejor que el primero, a la hora de reducir el tamaño de
los binarios compilados.
Compilación
Parámetros de compilación opcionales
-v : Muestra más información en el proceso de compilación.
-j$(nproc)
: Establece el número de procesos de compilación en
paralelo, en función del número de núcleos e hilos
que tenga nuestro procesador, tomando como referencia la
información mostrada por el sistema con el comando
correspondiente. Si nuestro procesador es mononúcleo de un solo
hilo, no añadir esta opción.
Instalación como root de la versión de 32 bits
$ su
# ninja -C build32 install/strip
# mv /opt/llvm19/bin/llvm-config{,-32}
# exit
$ cd ..
|
Explicación de los comandos
mv /opt/llvm19/bin/llvm-config{,-32}
: Renombramos el ejecutable encargado de mostrar la
información sobre la ubicación de las librerías de
LLVM en los procesos de compilación en los que sea necesario su
uso, siguiendo el método utilizado por el CLFS.
2) Configuración de la versión de 64 bits estática
$ mkdir -p build64/bin; echo '--gcc-toolchain=/opt/gcc14' | tee build64/bin/clang{,++}.cfg &> /dev/null
$ cmake -S llvm -B build64 -DLLVM_ENABLE_PROYECTS="clang;lld;polly;compiler-rt;openmp" \
-DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind" -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/opt/llvm19 -DLLVM_TARGETS_TO_BUILD="X86;AMDGPU;BPF" \
-DLLVM_BINUTILS_INCDIR=/usr/include -DLLVM_BUILD_DOCS=ON -DLLVM_ENABLE_SPHINX=ON \
-DSPHINX_WARNINGS_AS_ERRORS=OFF -DOCAMLFIND=null -DLLVM_LIBDIR_SUFFIX=64 \
-DLLVM_ENABLE_RTTI=ON -DLLVM_ENABLE_FFI=ON -DLLVM_INSTALL_UTILS=ON -DLLVM_ENABLE_DUMP=ON
\ -DLIB{,CXX,CXXABI,UNWIND,}_INSTALL_LIBRARY_DIR=/opt/llvm19/lib64 \
-DOPENMP_INSTALL_LIBDIR=/opt/llvm19/lib64 -DLLVM_SPIRV_INCLUDE_TESTS=OFF \
-DLIBOMP_ARCHER_SUPPORT=OFF -DLIBUNWIND_SUPPORTS_{FNO_EXCEPTIONS,FUNWIND_TABLES}_FLAG=ON -G Ninja |
Explicación de los comandos
mkdir -p build64/bin; echo '--gcc-toolchain=/opt/gcc14' | tee build64/bin/clang{,++}.cfg &> /dev/null : Establece la ruta de instalación de GCC,
en el caso de que utilicemos otra versión diferente a la
principal del
sistema o ésta, esté ubicada en un directorio no
habitual, creando dos archivos de configuración para clang,
clang.cfg y clang++.cfg, para la versión de Clang que se
generará en el proceso de compilación. Esto viene a
sustituir a la opción de configuración de CMake, -DGCC_INSTALL_PREFIX=, que pasó a ser obsoleta a partir de la versión 18 de Clang y se ha retirado en la versión 19.
Estos mismos archivos también deberán ser creados en el
directorio final de instalación de los ejecutables de Clang.
Cuando se actualice GCC a una versión completa superior, ya no
será necesario recompilar Clang, bastará con editar estos
archivos y cambiar la ruta a la nueva versión de GCC instalada.
-S llvm -B build64 : Establece el directorio del código fuente y el directorio de compilación.
-DLLVM_ENABLE_PROJECTS="clang;lld;polly;compiler-rt;openmp":
Activa la compilación de los proyectos separados por
punto y coma, incluidos junto a LLVM en el paquete proporcionado en
este manual. Además de estos proyectos, el paquete incluye los
siguientes: bolt, clang-tools-extra, flang, libc, libcl, lldb, mlir y
pstl, que podemos añadir si así lo deseamos, a este
parámetro de configuración, aunque algunos como libclc,
no se compilan de forma efectiva y hay que compilarlos aparte.
-DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind"
: A partir de la versión 16 de LLVM, no es posible incluir todos
los paquetes como proyectos y debemos añadir este
parámetro en lo que respecta a los paquetes libcxx, libcxxabi y
libunwind, que serán compilados por la versión de Clang,
generada en el proceso de compilación.
-DCMAKE_BUILD_TYPE=Release : Compila la versión optimizada de LLVM.
-DCMAKE_INSTALL_PREFIX=/opt/llvm19 : Instala el compilador en /opt/llvm19.
-DLLVM_TARGETS_TO_BUILD="X86;AMDGDPU;BPF" : Compila sólo el soporte de la arquitectura de procesador x86, el soporte del controlador de gráficos de código abierto, AMDGPU (requerido para poder compilar Mesa con soporte de las tarjetas gráficas de AMD) y el soporte de BPF, requerido para la compilación del paquete v4l-utils, omitiendo otras como ARM, PowerPC, etc. Esto reduce el tiempo de
compilación y el tamaño del directorio de
instalación del compilador.
-DLLVM_BINUTILS_INCDIR=/usr/include : Le indicamos la ruta al archivo de cabecera plugin-api.h, proporcionado por el paquete Binutils cuando se instala con soporte de plugins. Esta versión especial es requerida para poder compilar el plugin LLVM Gold, que nos permite poder disponer de la optimización LTO, en las compilaciones que realicemos con Clang.
-DLLVM_BUILD_DOCS=ON : Activa la creación e instalación de la documentación en formato HTML y páginas de manual de LLVM y Clang.
-DLLVM_ENABLE_SPHINX=ON : Utiliza el programa Sphinx para crear la documentación en formato HTML y páginas de manual de LLVM y Clang.
-DSPHINX_WARNINGS_AS_ERRORS=OFF : Evita que los avisos sean tratados como errores, al generar la documentación en formato HTML y páginas de manual de LLVM y Clang.
-DOCAMLFIND=null : Al no tener el paquete una opción específica para desactivar la adaptación de LLVM para el lenguaje de programación OCaml, le indicamos una ruta nula al ejecutable ocamlfind,
para poder desactivar el soporte de esta dependencia. Si no tenemos
instalado OCaml en nuestro sistema, esto no hay que añadirlo.
-DLLVM_LIBDIR_SUFFIX=64 : Establece el nombre del directorio de las librerías de LLVM en lib64,
para que no sean sobrescritas en el proceso de instalación, las
librerías de la versión de 32 bits, ubicadas en /opt/llvm19/lib.
-DLLVM_ENABLE_RTTI=ON : Parámetro requerido para poder compilar Mesa con soporte de LLVM con el sistema de compilación, Meson.
-DLLVM_ENABLE_FFI=ON : Activa el soporte de Libffi, librería de características similares a GMP.
-DLLVM_INSTALL_UTILS=ON : Instala las utilidades binarias FileCheck, count, lli-child-target, llvm-PerfectShutffle, not y yaml-bench
que, en el caso de FileCheck es requerido en la compilación de
algún paquete de código fuente, cuyo nombre ahora no
recuerdo. Estas utilidades se compilan por defecto, pero para
instalarlas hay que añadir esta variable al comando de
configuración del paquete.
-DLLVM_ENABLE_DUMP=ON : Requerido para poder compilar el soporte del experimental controlador gallium-rusticl de las librerías Mesa.
-DLIB{,CXX,CXXABI,UNWIND,}_INSTALL_LIBRARY_DIR=/opt/llvm19/lib64
: Evita a partir de LLVM 15, que las librerías libc++, libc++abi
y libunwind, se instalen en el directorio
/opt/llvm19/lib64/x86_64-unknown-linux-gnu, ubicándolas en el
directorio predefinido de siempre.
-DOPENMP_INSTALL_LIBDIR=/opt/llvm19/lib64 : Lo mismo que en el parámetro anterior, pero en este caso con libomp, a partir de LLVM 19.
-DLIBOMP_ARCHER_SUPPORT=OFF
: Desactiva la compilación de libarcher como dependencia de
Libomp, destinada a depurar la ejecución de aplicaciones
compatibles con OpenMP. La no inclusión de esta opción,
obligaba a enlazar contra libtsan (proporcionada por GCC), todas las
aplicaciones que se compilaban con este soporte, en Clang 17.
-DLIBUNWIND_SUPPORTS_{FNO_EXCEPTIONS,FUNWIND_TABLES}_FLAG=ON : Evita errores de compilación de Libunwind, como dependencia de Libc++.
-G Ninja : Utiliza Ninja en lugar de GNU Make para compilar el paquete (opcional).
Parámetros de configuración opcionales
-DCMAKE_{C,CXX}_COMPILER_LAUNCHER=ccache : Activa el uso de Ccache
en el proceso de compilación. Si tenemos configurado Ccache con
los correspondientes enlaces simbólicos, no es necesario
añadir esta opción. Pero sí tenemos que tener activadas las opciones de Ccache, hash_dir y run_second_cpp,
que vienen activadas por defecto. En la 3ª fase de compilación sí que
es necesario añadirla. Se puede sustituir ccache por buildcache o
sccache, cuyos manuales de instalación se encuentran en esta web.
-DLLVM_BUILD_LLVM_DYLIB=ON:
Compila una librería única compartida de LLVM, a partir
de las estáticas, para poder enlazar contra la misma, paquetes
como las librerías Mesa.
Si no tenemos pensado compilar la versión compartida de LLVM,
tendremos que añadir esta opción a las opciones de
configuración del paquete.
-DLLVM_TOOL_SPIRV_LLVM_TRANSLATOR_BUILD=OFF
: Omite la compilación de SPIRV-LLVM-Translator, si no tenemos pensado compilar Libclc.
-DLLVM_ENABLE_LTO=ON|Thin : Activa el uso de la optimización LTO,
tanto con GCC como con Clang, siempre en combinación con el
parámetro anteriormente descrito. La reducción de los
archivos binarios es irrelevante, penalizado por el aumento de
tamaño de las librerías estáticas, si
utilizamos la optimización ThinLTO con Clang. La ganancia de
velocidad (10/15 % en las comparativas de este manual) y el menor
tamaño de los binarios que genera el compilador,
independientemente de la optimización que se utilice, sí
es relevante. Si vamos a utilizar Clang, muy recomendable hacer uso de
ThinLTO en lugar de LTO, estableciendo Thin en lugar de ON, en el valor de este parámetro, para reducir el tiempo de compilación del paquete. (en versiones inferiores a Clang 17). A partir de la versión 17
de Clang, es recomendable utilizar la opción LTO, en combinación con
las optimizaciones Unified LTO, si se utiliza Clang para compilar el
paquete.
-DLLVM_ENABLE_LLD=ON
: Este parámetro sólo es necesario si utilizamos la
optimización ThinLTO con Clang, y no tenemos configurado un
directorio caché para LLD en nuestro sistema, cuyo uso hemos
establecido con la correspondiente variable de entorno de uso de
enlazador dinámico para LLD. El proceso de configuración
creará uno en la raíz del directorio de
compilación con el nombre lto.cache
y almacenará en el mismo los archivos objeto que se generen en
el proceso de enlazado, evitando utilizar la memoria física del
sistema, si tenemos montado el directorio /tmp con el sistema de archivos, Tmpfs.
Si se establece LLD como enlazador dinámico, antes del comando
de configuración del paquete, esta opción no será
funcional.
-DLLVM_PARALLEL_LINK_JOBS=$(nproc)
: Establece el número de procesos en paralelo de enlazado de los
binarios (por defecto es 2), tomando como referencia la
información del número de núcleos de nuestro
procesador, proporcionada por el sistema. Este parámetro
sólo es aplicable con Ninja. Si compilamos el paquete con Clang, estableciendo las correspondientes
variables de entorno de LLD de este manual, es recomendable no utilizar esta opción.
-DCMAKE_STRIP=/usr/bin/strip : Sustituye llvm-strip por strip,
en el caso de que compilemos el paquete con Clang. El segundo es
bastante mejor que el primero, a la hora de reducir el tamaño de
los binarios compilados.
Compilación
Parámetros de compilación opcionales
Instalación como root de la versión de 64 bits estática
$ su
# ninja -C build64 install/strip
# mv /opt/llvm19/bin/llvm-config{,-64}
# ln -sf /opt/llvm19/lib64/LLVMgold.so /usr/lib64/bfd-plugins
# echo '--gcc-toolchain=/opt/gcc14' | tee /opt/llvm19/bin/clang{,++}.cfg &> /dev/null |
Explicación de los comandos
mv /opt/llvm19/bin/llvm-config{,-64}
: Renombramos el ejecutable encargado de mostrar la
información sobre la ubicación de las librerías de
LLVM en los procesos de compilación en los que sea necesario su
uso, siguiendo el método utilizado por el CLFS.
ln -sf /opt/llvm19/lib64/LLVMgold.so /usr/lib64/bfd-plugins : Crea un enlace simbólico del plugin LTO de LLVM al directorio de plugins de las GNU Binutils.
Esto evita tener que establecer las variables de entorno AR, NM
y RANLIB, en los procesos de compilación que se utiliza la
optimización LTO, con GNU gold. La
ubicación del directorio de plugins, pueden variar según
la distribución que estemos utilizando.
echo '--gcc-toolchain=/opt/gcc14' | tee /opt/llvm19/bin/clang{,++}.cfg &> /dev/null : Ya explicado más arriba, establece la ruta de instalación de GCC,
en el caso de que utilicemos otra versión diferente a la
principal del
sistema o ésta, esté ubicada en un directorio no
habitual, creando dos archivos de configuración, clang.cfg y
clang++.cfg, en el directorio de instalación de los ejecutables
de Clang.
Crear el binario ejecutable selector de arquitectura de procesador siguiendo el método del CLFS
Nos descargamos este archivo
y lo compilamos como root con el siguiente comando, para posteriormente
crear el enlace simbólico correspondiente para poder alternar de
una arquitectura a otra, en el uso de dependencias, en función
del proceso de compilación en curso.
# gcc multiarch_wrapper.c -o /opt/llvm19/bin/multiarch_wrapper
# ln -s multiarch_wrapper /opt/llvm19/bin/llvm-config
|
Cuando compilemos código de 32 bits, que necesite de las
dependencias de las librerías de 32 bits de LLVM, ejecutamos la
siguiente variable de entorno, antes de configurar los paquetes de
código fuente correspondientes.
Crear dos scripts de enlazador de libc++ y libomp en /usr/lib64
Para no tener que establecer variable de entorno alguna de
ubicación de estas librerías instaladas en /opt/llvm19/lib64, en los procesos de
compilación pertinentes, crearemos dos
scripts de enlazador, libc++.so y libomp.so, en /usr/lib64.
# echo -e '/*
GNU ld script */\nINPUT(/opt/llvm19/lib64/libc++.so.1
/opt/llvm19/lib64/libc++abi.so /opt/llvm19/lib64/libunwind.so)' > /usr/lib64/libc++.so
# echo -e '/* GNU ld script */\nINPUT(/opt/llvm19/lib64/libomp.so)' > /usr/lib64/libomp.so |
La inclusión de estos scripts en este manual de
instalación, conlleva la actualización de los manuales de
la web en los que se hace uso de estas librerías, retirando el
comando de ubicación de directorio que se incluía en la
variable de entorno LDFLAGS pertinente.
Configuración de Libclc
Este apartado sólo es para los usuarios
de tarjetas
gráficas de AMD, que quieran hacer uso de OpenCL con las
librerías Mesa. Para ello necesitaremos instalar Libclc y
SPIRV-LLVM-Translator (requerido sólo el binario ejecutable para compilar Libclc) y
también, requerido para compilar el soporte de SPIRV en el
controlador Clover de Gallium de las librerías Mesa. La
versión de SPIRV-LLVM-Translator tiene que ser siempre la misma
que la serie de LLVM, incluyendo claro está las versiones de
corrección de errores de LLVM. En el paquete incluido en este
manual de LLVM, ya existe una versión que he añadido para
ahorrarnos más enlaces de descarga.
Utilizaremos los binarios ejecutables creados en la anterior
compilación, estableciendo las correspondientes variables de
entorno.
$ export PATH=$PWD/build64/bin:$PATH
$ export LLVM_DIR=$PWD/build64/lib64/cmake/llvm
$ cd libclc
$ cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/opt/llvm19 -G Ninja |
Compilación
Instalación como root
$ su -c "ninja -C build install"
$ unset LLVM_DIR
$ cd ..
|
3) Configuración
de la versión de 64 bits compartida (sólo librerías de LLVM, Clang, Polly y SPIRV-LLVM-Translator)
Esta opción soluciona problemas de enlazado de paquetes como
SPIRV-LLVM-Translator, que mezclan librerías de LLVM compartidas
con estáticas en el proceso de enlazado con duplicación
de símbolos, produciendo errores de
ejecución y compilación en paquetes como Mesa, cuando
compilamos el soporte de OpenCL en las mismas. Lo bueno de esta
opción es que reduce la instalación anterior de LLVM en
1,3 GB. Se utilizan los binarios ejecutables creados en la anterior
compilación y establecemos el PATH correspondiente de su
ubicación. Si estamos utilizando la misma ventana de terminal de
la compilación de Libclc, no es necesario establecer la variable
de entorno PATH.
$ export PATH=$PWD/build64/bin:$PATH
$ cmake -S llvm -B build64s -DLLVM_ENABLE_PROYECTS="clang;polly" -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/opt/llvm19 -DBUILD_SHARED_LIBS=ON -DLLVM_TARGETS_TO_BUILD="X86;AMDGPU;BPF" \
-DLLVM_BINUTILS_INCDIR=/usr/include -DOCAMLFIND=null -DLLVM_LIBDIR_SUFFIX=64 \
-DLLVM_ENABLE_RTTI=ON -DLLVM_ENABLE_FFI=ON -DCLANG_BUILD_TOOLS=OFF \
-DLLVM_ENABLE_LTO=ON -DLLVM_ENABLE_DUMP=ON -DLLVM_SPIRV_INCLUDE_TESTS=OFF -G Ninja |
Compilación
Instalación
como root de la versión de 64 bits compartida (sólo
librerías de LLVM, Clang, Polly y SPIRV-LLVM-Translator)
$ su
# ninja -C build64s install/strip
# mv /opt/llvm19/bin/llvm-config{,-64}
# ln -s multiarch_wrapper /opt/llvm19/bin/llvm-config |
Borrar las librerías estáticas de la 2ª fase de compilación
Esto es opcional, pero su instalación ocupa casi 500 MB. Al
instalar la versión compartida de LLVM, éstas quedan
anuladas en cualquier proceso de compilación que realicemos, a
no ser que forcemos una compilación estática, algo poco
habitual en un proceso de compilación en nuestro sistema.
# find /opt/llvm19/lib64 -maxdepth 1 -name '*.a' -type f -delete |
Borrar los archivos de instalación que hacen referencia a la
versión 19.1.3, sobrescrita por esta nueva versión
Hacer sólo esto si estamos actualizando desde la versión
anterior instalada siguiendo las instrucciones de este manual. Con el
siguiente comando, borramos los archivos de instalación
de la versión anterior.
# for i in 19.1.3 ; do \
rm -f /opt/llvm19/lib{,64}/libclang.so.$i ; \
done |
Estadísticas de Compilación e Instalación de LLVM
Estadísticas de Compilación e Instalación de LLVM |
CPU |
AMD Ryzen 5 5500 |
MHz |
3600 (BoostMax=4457) |
RAM |
32 GB |
Sistema de archivos |
XFS |
Versión del Kernel |
6.12.0-ml SMP PREEMPT_DYNAMIC x86_64 |
Modo de frecuencia de la CPU |
powersave (balance performance) |
Planificador de CPU |
BMQ |
Versión de Glibc |
2.40 |
Enlazador dinámico |
LLD 19.1.3 |
Compilador |
Clang 19.1.3 + Sccache 0.8.2 |
Parámetros de optimización del modo de 32 bits |
-03 -march=i686
-mtune=athlon-xp -mllvm -polly -mllvm -polly-vectorizer=stripmine
-flto -funified-lto -Wl,--lto=thin -Wl,--thinlto-jobs=6 -Wl,--lto-aa-pipeline=globals-aa
-Wl,--lto-newpm-passes=memcpyopt |
Parámetros de optimización del modo de 64 bits |
-03 -march=znver3
-mtune=znver3 -mllvm -polly -mllvm -polly-vectorizer=stripmine
-flto -funified-lto -Wl,--lto=thin -Wl,--thinlto-jobs=6 -Wl,--lto-aa-pipeline=globals-aa
-Wl,--lto-newpm-passes=memcpyopt |
Parámetros de compilación |
-v -j12 |
Ocupación de espacio en disco del proceso de compilación |
10,0 GB |
Tiempo de compilación de la versión de 32 bits |
28' 27" |
Tiempo de compilación de la versión de 64 bits estática (incluye libclc) |
1h 01' 10" |
Tiempo de compilación de la versión de 64 bits compartida |
28' 12" |
Tiempo total consumido |
1h 57' 49" |
Archivos instalados |
8.549 |
|
Enlaces simbólicos creados |
462 |
|
Ocupación de espacio en disco |
1,6 GB |
Desinstalación como root
1) MODO TRADICIONAL
Este programa no tiene soporte para desinstalación con el comando 'ninja uninstall'
2) MODO MANUALINUX
El principal inconveniente del comando anterior es que tenemos que
tener el directorio de compilación en nuestro sistema para poder
desinstalar el programa. En algunos casos esto supone muchos megas de
espacio en disco. Con el paquete de scripts que pongo a
continuación logramos evitar el único inconveniente que
tiene la compilación de programas, y es el tema de la
desinstalación de los mismos sin la necesidad de tener
obligatoriamente una copia de las fuentes compiladas.
llvm-19.1.4-scripts.tar.gz
$ su
# tar zxvf llvm-19.1.4-scripts.tar.gz
# cd llvm-19.1.4-scripts
# ./Desinstalar_llvm-19.1.4 |
Copia de Seguridad como root
Con este otro script creamos una copia de seguridad de los binarios
compilados, recreando la estructura de directorios de los mismos en un
directorio de copias de seguridad (copibin) que se crea en el directorio /var. Cuando se haya creado el paquete comprimido de los binarios podemos copiarlo como usuario a nuestro home
y borrar el que ha creado el script de respaldo, teniendo en cuenta que
si queremos volver a restaurar la copia, tendremos que volver a
copiarlo al lugar donde se ha creado.
$ su
# tar zxvf llvm-19.1.4-scripts.tar.gz
# cd llvm-19.1.4-scripts
# ./Respaldar_llvm-19.1.4 |
Restaurar la Copia de Seguridad como root
Y con este otro script (que se copia de forma automática cuando
creamos la copia de respaldo del programa) restauramos la copia de
seguridad como root cuando resulte necesario.
$ su
# cd /var/copibin/restaurar_copias
# ./Restaurar_llvm-19.1.4
|
Configurar el sistema para el uso de Clang
1) /etc/ld.so.conf
Añadimos la ruta a las librerías compartidas en el archivo /etc/ld.so.conf.
include ld.so.conf.d/*.conf
/usr/X11R6/lib
/usr/lib
/usr/lib/qt3/lib
/usr/local/lib
/opt/e17/lib
/opt/llvm19/lib64
/opt/llvm19/lib
|
Cuando lo hayamos editado y guardado ejecutamos la actualización de la caché de las librerías compartidas.
2) Añadir la ruta a los binarios y las páginas de manual a nuestro PATH
2a) Variable de entorno PATH de usuario
Editamos el archivo de nuestro home, ~/.bashrc (si no existe lo creamos) y añadimos lo siguiente al final del mismo:
export PATH=/opt/llvm19/bin:$PATH
export MANPATH=/opt/llvm19/share/man:$MANPATH
|
2b) Variable de entorno PATH del sistema
Si queremos establecer una variable de entorno global del sistema, abrimos un editor de texto y añadimos lo siguiente:
#!/bin/sh
export PATH=/opt/llvm19/bin:$PATH
export MANPATH=/opt/llvm19/share/man:$MANPATH
|
Lo guardamos con el nombre clang.sh, y lo instalamos en /etc/profile.d.
$ su -c "install -m755 clang.sh /etc/profile.d" |
Tenemos que cerrar el emulador de terminal y volverlo a abrir para que
la variable de entorno aplicada sea efectiva. Es conveniente guardar
una copia de este script para posteriores instalaciones de nuestro
sistema. La ventaja de utilizar el directorio /etc/profile.d es que es común a todas las distribuciones y nos evita tener que editar otros archivos del sistema como por ejemplo, /etc/profile.
Para comprobar que el binario clang está incluido en el path, abrimos una ventana de terminal y ejecutamos el siguiente comando:
[jose@localhost ~]$ clang --version
clang version 19.1.4
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /opt/llvm19/bin
Configuration file: /opt/llvm19/bin/clang.cfg
|
2c) Lectura de las páginas de manual
2d) Lectura de la documentación en formato HTML
/opt/llvm19/share/doc/LLVM/llvm/html/index.html | /opt/llvm19/share/doc/LLVM/clang/html/index.html
2) Establecer la variable PKG_CONFIG_PATH requerida por el programa pkg-config
Establecemos la correspondiente variable de entorno para que el programa pkg-config encuentre
los archivos de referencia (*.pc) de las dependencias
requeridas en los procesos de compilación pertinentes.
Sólo es necesario si hemos instalado las
librerías LLVMSPIRVLib y Libclc, siguiendo este manual.
En el archivo que hemos creado anteriormente (clang.sh) añadimos lo que está en rojo:
#!/bin/sh
export PATH=/opt/llvm19/bin:$PATH
export MANPATH=/opt/llvm19/share/man:$MANPATH
export
PKG_CONFIG_PATH=/opt/llvm19/lib64/pkgconfig:/opt/llvm19/share/pkgconfig:$PKG_CONFIG_PATH
|
En la versión de 32 bits de LLVMSPIRVLib y, además,
Libclc, que no es una librería propiamente dicho, allí
donde se
requiera su dependencia lo haremos de forma manual, añadiendo la
ruta correspondiente a la variable de entorno PKG_CONFIG_PATH a
establecer, un ejemplo:
$ export PKG_CONFIG_PATH=/usr/lib/pkgconfig:/usr/local/lib/pkgconfig:\
/opt/llvm19/lib/pkgconfig:/opt/llvm19/share/pkgconfig:/usr/share/pkgconfig:$PKG_CONFIG_PATH
|
Optimizaciones de CPU para Clang
Los procesadores soportados por Clang, son practicamente los mismos que los de GCC,
con las excepciones en las que se permite más de una
definición para hacer referencia a un determinado procesador.
Por ejemplo, barcelona no está soportado por Clang, hasta la versión 3.6, con lo que tendremos que utilizar el otro término alternativo: amdfam10. El parámetro '-mtune' ha sido introducido a partir de la versión 3.4 de Clang. Si utilizamos versiones anteriores, tendremos que utilizar '-mcpu'.
La tabla que pongo a
continuación no difiere mucho de la utilizada en los manuales de
instalación ubicados en la web, las filas con el color amarillo
indican las definiciones de procesador soportadas por Clang, que no aparecen en las opciones de optimización de GCC.
$ export {C,CXX}FLAGS='-O3 -march=znver3 -mtune=znver3'
|
Donde pone znver3 se indica el procesador respectivo de cada sistema seleccionándolo de la siguiente tabla: |
Nota informativa sobre las optimizaciones para GCC
|
* La opción '-march=' establece el procesador mínimo con el que funcionará el programa compilado, la opción '-mtune=' el procesador específico para el que será optimizado.
* Los valores separados por comas, son equivalentes, es decir, que lo mismo da poner '-march=k8' que '-march=athlon64'.
* En versiones de GCC 3.2 e inferiores se utiliza la opción '-mcpu=' en lugar de '-mtune='.
|
Nota informativa sobre las optimizaciones para Clang
|
* La opción '-mtune=' está soportada a partir de la versión 3.4 de Clang.
* Los valores de color azul no son compatibles con Clang.
* Las filas con el fondo de color amarillo son valores exclusivos de Clang y, por lo tanto, no son aplicables con GCC.
|
Valores |
CPU |
Genéricos |
generic |
Produce un código
binario optimizado para la mayor parte de procesadores existentes.
Utilizar este valor si no sabemos el nombre del procesador que tenemos
en nuestro equipo. Este valor sólo es aplicable en la
opción '-mtune=', si utilizamos GCC. Esta opción está disponible a partir de GCC 4.2. |
native |
Produce un código
binario optimizado para el procesador que tengamos en nuestro sistema,
siendo éste detectado utilizando la instrucción cpuid.
Procesadores antiguos pueden no ser detectados utilizando este valor.
Esta opción está disponible a partir de GCC 4.2. |
x86-64 |
Procesador genérico con extensiones 64-bit. Esta opción está disponible a partir de GCC 8 y Clang 1.9. |
x86-64-v2 |
Procesador
genérico con con soporte de instrucciones X86-64 (MMX, SSE,
SSE2, LAHFSAHF, POPCNT, SSE3, SSE4.1, SSE4.2, SSSE3) y extensiones
64-bit. Esta opción está disponible a partir de GCC 11 y Clang 12. |
x86-64-v3 |
Procesador
genérico con con soporte de instrucciones X86-64 (MMX, SSE,
SSE2, LAHFSAHF, POPCNT, SSE3, SSE4.1, SSE4.2, SSSE3, AVX, AVX2, F16C,
FMA, LZCNT, MOVBE, XSAVE, XSAVEC, FMA4) y extensiones 64-bit. Esta
opción está disponible a partir de GCC 11 y Clang 12. |
x86-64-v4 |
Procesador
genérico con con soporte de instrucciones X86-64 (MMX, SSE,
SSE2, LAHFSAHF, POPCNT, SSE3, SSE4.1, SSE4.2, SSSE3, AVX, AVX2, F16C,
FMA, LZCNT, MOVBE, XSAVE, XSAVEC, AVX512*, FMA4) y extensiones 64-bit.
Esta opción está disponible a partir de GCC 11 y Clang 12. |
Intel |
alderlake |
Intel Alderlake con
soporte de instrucciones x86-64 (MOVBE, MMX, SSE, SSE2, SSE3, SSSE3,
SSE4.1, SSE4.2, POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND,
FMA, BMI, BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC,
XSAVES, AVX512F, CLWB, AVX512VL, AVX512BW, AVX512DQ, AVX512CD,
AVX512VNNI, AVX512BF16, MOVDIRI, MOVDIR64B, AVX512VP2INTERSECT, ENQCMD,
CLDEMOTE, PTWRITE, WAITPKG, SERIALIZE, TSXLDTRK, UINTR, AMX-BF16,
AMX-TILE, AMX-INT8, AVX-VNNI) y extensiones 64-bit. Esta opción
está disponible a partir de GCC 11 y Clang 12. |
arrowlake |
Intel Arrow Lake con
soporte de instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1,
SSE4.2, POPCNT, AES, PREFETCHW, PCLMUL, RDRND, XSAVE, XSAVEC, XSAVES,
XSAVEOPT, FSGSBASE, PTWRITE, RDPID, SGX, GFNI-SSE, CLWB, MOVDIRI,
MOVDIR64B, CLDEMOTE, WAITPKG, ADCX, AVX, AVX2, BMI, BMI2, F16C, FMA,
LZCNT, PCONFIG, PKU, VAES, VPCLMULQDQ, SERIALIZE, HRESET, KL, WIDEKL,
AVX-VNNI, UINTR, AVXIFMA, AVXVNNIINT8, AVXNECONVERT, CMPCCXADD y
extensiones 64-bit. Esta opción está disponible a partir
de GCC 14. |
arrowlake-s |
Intel Arrow Lake S con
soporte de instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1,
SSE4.2, POPCNT, AES, PREFETCHW, PCLMUL, RDRND, XSAVE, XSAVEC, XSAVES,
XSAVEOPT, FSGSBASE, PTWRITE, RDPID, SGX, GFNI-SSE, CLWB, MOVDIRI,
MOVDIR64B, CLDEMOTE, WAITPKG, ADCX, AVX, AVX2, BMI, BMI2, F16C, FMA,
LZCNT, PCONFIG, PKU, VAES, VPCLMULQDQ, SERIALIZE, HRESET, KL, WIDEKL,
AVX-VNNI, UINTR, AVXIFMA, AVXVNNIINT8, AVXNECONVERT, CMPCCXADD,
AVXVNNIINT16, SHA512, SM3, SM4 y extensiones 64-bit. Esta opción
está disponible a partir de GCC 14. |
atom |
Intel Atom con soporte de
instrucciones MMX, SSE, SSE2, SSE3, SSSE3 y extensiones
64-bit. Esta opción está disponible desde GCC 4.6, hasta GCC 4.8. A partir de GCC 4.9 se utiliza la definición bonnell. |
bonnell |
Intel Bonnell con soporte
de instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3 y extensiones
64-bit. Esta opción está disponible a partir de GCC 4.9. |
broadwell |
Intel Broadwell con
soporte de instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1,
SSE4.2, POPCNT, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI,
BMI2, F16C, RDSEED, ADCX, PREFETCHW y extensiones 64-bit. Esta
opción está disponible a partir de GCC 4.9 y Clang 3.6. |
cannonlake |
Intel Cannonlake Server
con soporte de instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3,
SSE4.1, SSE4.2, POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND,
FMA, BMI, BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC,
XSAVES, AVX512F, AVX512VL, AVX512BW, AVX512DQ, AVX512CD, AVX512VBMI,
AVX512IFMA, SHA, UMIP y extensiones 64-bit. Esta opción
está disponible a partir de GCC 8 y Clang 3.9. |
cascadelake |
Intel Cascadelake con
soporte de instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1,
SSE4.2, POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI,
BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC, XSAVES,
AVX512F, CLWB, AVX512VL, AVX512BW, AVX512DQ, AVX512CD, AVX512VNNI y
extensiones 64-bit. Esta opción está disponible a
partir de GCC 9 y Clang 8. |
clearwaterforest |
Intel
Clearwater Forest con soporte de instrucciones MOVBE, MMX, SSE, SSE2,
SSE3, SSSE3, SSE4.1, SSE4.2, POPCNT, AES, PREFETCHW, PCLMUL, RDRND,
XSAVE, XSAVEC, XSAVES, XSAVEOPT, FSGSBASE, PTWRITE, RDPID, SGX,
GFNI-SSE, CLWB, MOVDIRI, MOVDIR64B, CLDEMOTE, WAITPKG, ADCX, AVX, AVX2,
BMI, BMI2, F16C, FMA, LZCNT, PCONFIG, PKU, VAES, VPCLMULQDQ, SERIALIZE,
HRESET, KL, WIDEKL, AVX-VNNI, ENQCMD, UINTR, AVXIFMA, AVXVNNIINT8,
AVXNECONVERT, CMPCCXADD, AVXVNNIINT16, SHA512, SM3, SM4, USER_MSR,
PREFETCHI y extensiones 64-bit. Esta opción está
disponible a partir de GCC 14 y Clang 18. |
cooperlake |
Intel
Cooper Lake con soporte de instrucciones MOVBE, MMX, SSE, SSE2, SSE3,
SSSE3, SSE4.1, SSE4.2, POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE,
RDRND, FMA, BMI, BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT,
XSAVEC, XSAVES, AVX512F, CLWB, AVX512VL, AVX512BW, AVX512DQ, AVX512CD,
AVX512VNNI, AVX512BF16 y extensiones 64-bit. Esta opción
está disponible a partir de GCC 10 y Clang 9. |
core2 |
Intel Core2
con soporte de instrucciones MMX, SSE, SSE2, SSE3, SSSE3 y
extensiones 64-bit. Esta opción está disponible a partir
de GCC 4.3. |
core-avx2 |
Intel Core (Haswell). Esta opción está disponible desde GCC 4.6, hasta GCC 4.8. A partir de GCC 4.9 se utiliza la definición haswell. |
core-avx-i |
Intel Core (ivyBridge)
con soporte de instrucciones MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1,
SSE4.2, AVX, AES, PCLMUL, FSGSBASE, RDRND, F16C y extensiones
64-bit. Esta opción está disponible desde GCC 4.6, hasta GCC 4.8. A partir de GCC 4.9 se utiliza la definición ivybridge. |
corei7 |
Intel Core i7
con soporte de instrucciones MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1 y
SSE4.2 y extensiones 64-bit. Soporta también los procesadores
Intel Core i3 e i5. Esta opción está disponible
desde GCC 4.6, hasta GCC 4.8. A partir de GCC 4.9 se utiliza la definición nehalem. |
corei7-avx |
Intel Core i7 con
soporte de instrucciones MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2,
AVX, AES y PCLMUL y extensiones 64-bit. Soporta también los
procesadores Intel Core i3 e i5. Esta opción está
disponible desde GCC 4.6, hasta GCC 4.8. A partir de GCC 4.9 se utiliza la definición sandybridge. |
emeraldrapids |
Intel Emerald Rapids. Esta opción está disponible a partir de GCC 13 y Clang 16. |
goldmont |
Intel Goldmont con soporte
de instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2,
POPCNT, AES, PCLMUL, RDRND, XSAVE, XSAVEOPT, FSGSBASE y extensiones
64-bit. Esta opción está disponible a partir de GCC 9 y Clang 5. |
goldmont-plus |
Intel Goldmont Plus con
soporte de instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1,
SSE4.2, POPCNT, AES, PCLMUL, RDRND, XSAVE, XSAVEOPT, FSGSBASE, PTWRITE,
RDPID, SGX, UMIP y extensiones 64-bit. Esta opción está
disponible a partir de GCC 9 y Clang 7. |
grandridge |
Intel Grand Ridge con
soporte de instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1,
SSE4.2, POPCNT, AES, PREFETCHW, PCLMUL, RDRND, XSAVE, XSAVEC, XSAVES,
XSAVEOPT, FSGSBASE, PTWRITE, RDPID, SGX, GFNI-SSE, CLWB, MOVDIRI,
MOVDIR64B, CLDEMOTE, WAITPKG, ADCX, AVX, AVX2, BMI, BMI2, F16C, FMA,
LZCNT, PCONFIG, PKU, VAES, VPCLMULQDQ, SERIALIZE, HRESET, KL, WIDEKL,
AVX-VNNI, AVXIFMA, AVXVNNIINT8, AVXNECONVERT, CMPCCXADD, RAOINT y
extensiones 64-bit. Esta opción está disponible a partir
de GCC 13 y Clang 16. |
graniterapids |
Intel Grand Ridge con
soporte de instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1,
SSE4.2, POPCNT, CX16, SAHF, FXSR, AVX, XSAVE, PCLMUL, FSGSBASE, RDRND,
F16C, AVX2, BMI, BMI2, LZCNT, FMA, MOVBE, HLE, RDSEED, ADCX, PREFETCHW,
AES, CLFLUSHOPT, XSAVEC, XSAVES, SGX, AVX512F, AVX512VL, AVX512BW,
AVX512DQ, AVX512CD, PKU, AVX512VBMI, AVX512IFMA, SHA, AVX512VNNI, GFNI,
VAES, AVX512VBMI2, VPCLMULQDQ, AVX512BITALG, RDPID, AVX512VPOPCNTDQ,
PCONFIG, WBNOINVD, CLWB, MOVDIRI, MOVDIR64B, AVX512VP2INTERSECT,
ENQCMD, CLDEMOTE, PTWRITE, WAITPKG, SERIALIZE, TSXLDTRK, UINTR,
AMX-BF16, AMX-TILE, AMX-INT8, AVX-VNNI, AVX512-FP16, AVX512BF16,
AMX-FP16, PREFETCHI y extensiones 64-bit. Esta opción
está disponible a partir de GCC 13 y Clang 16. |
graniterapids-d |
Intel Granite Rapids D con
soporte de instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1,
SSE4.2, POPCNT, CX16, SAHF, FXSR, AVX, XSAVE, PCLMUL, FSGSBASE, RDRND,
F16C, AVX2, BMI, BMI2, LZCNT, FMA, MOVBE, HLE, RDSEED, ADCX, PREFETCHW,
AES, CLFLUSHOPT, XSAVEC, XSAVES, SGX, AVX512F, AVX512VL, AVX512BW,
AVX512DQ, AVX512CD, PKU, AVX512VBMI, AVX512IFMA, SHA, AVX512VNNI, GFNI,
VAES, AVX512VBMI2, VPCLMULQDQ, AVX512BITALG, RDPID, AVX512VPOPCNTDQ,
PCONFIG, WBNOINVD, CLWB, MOVDIRI, MOVDIR64B, ENQCMD, CLDEMOTE, PTWRITE,
WAITPKG, SERIALIZE, TSXLDTRK, UINTR, AMX-BF16, AMX-TILE, AMX-INT8,
AVX-VNNI, AVX512FP16, AVX512BF16, AMX-FP16, PREFETCHI, AMX-COMPLEX y
extensiones 64-bit. Esta opción está disponible a partir
de GCC 14 y Clang 17. |
haswell |
Intel Haswell con soporte
de instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2,
POPCNT, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI, BMI2, F16C y
extensiones 64-bit. Esta opción está disponible a
partir de GCC 4.9. |
i386 |
Intel i386.
|
i486 |
Intel i486. |
i586, pentium |
Intel Pentium sin soporte de instrucciones MMX. |
i686 |
Produce un código
binario optimizado para la mayor parte de procesadores compatibles con
la serie 80686 de Intel. Todos los actuales lo son. |
icelake-client |
Intel Icelake Client con
soporte de instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1,
SSE4.2, POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI,
BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC, XSAVES,
AVX512F, AVX512VL, AVX512BW, AVX512DQ, AVX512CD, AVX512VBMI,
AVX512IFMA, SHA, CLWB, UMIP, RDPID, GFNI, AVX512VBMI2, AVX512VPOPCNTDQ,
AVX512BITALG, AVX512VNNI, VPCLMULQDQ, VAES y extensiones
64-bit. Esta opción está disponible a partir de GCC 8 y Clang 7. |
icelake-server |
Intel Icelake Server con
soporte de instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1,
SSE4.2, POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI,
BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC, XSAVES,
AVX512F, AVX512VL, AVX512BW, AVX512DQ, AVX512CD, AVX512VBMI,
AVX512IFMA, SHA, CLWB, UMIP, RDPID, GFNI, AVX512VBMI2, AVX512VPOPCNTDQ,
AVX512BITALG, AVX512VNNI, VPCLMULQDQ, VAES, PCONFIG, WBNOINVD y
extensiones 64-bit. Esta opción está disponible a
partir de GCC 8 y Clang 7. |
intel |
Intel Haswell y
Silvermont. Este valor sólo es aplicable en la
opción '-mtune='. Esta opción está disponible
a partir de GCC 4.9. |
ivybridge |
Intel Ivy Bridge con
soporte de instrucciones MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2,
POPCNT, AVX, AES, PCLMUL, FSGSBASE, RDRND, F16C y extensiones
64-bit. Esta opción está disponible a partir de GCC 4.9. |
knl |
Intel Knights Landing con
soporte de instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1,
SSE4.2, POPCNT, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI,
BMI2, F16C, RDSEED, ADCX, PREFETCHW, AVX512F, AVX512PF, AVX512ER y
extensiones 64-bit. Esta opción está disponible a
partir de GCC 5 y Clang 3.4. |
knm |
Intel Knights Mill con
soporte de instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1,
SSE4.2, POPCNT, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI,
BMI2, F16C, RDSEED, ADCX, PREFETCHW, AVX512F, AVX512PF, AVX512ER,
AVX512CD, AVX5124VNNIW, AVX5124FMAPS, AVX512VPOPCNTDQ y extensiones
64-bit. Esta opción está disponible a partir de GCC 8 y Clang 6. |
lakemont |
Intel Quark Lakemont MCU, basado en el procesador Intel Pentium. Esta opción está disponible a partir de GCC 6 y Clang 3.9. |
lunarlake |
Intel Lunar Lake. Esta opción está disponible a partir de GCC 14 y es equivalente a la opción arrowlake-s. |
meteorlake |
Intel Meteor Lake. Esta opción está disponible a partir de GCC 13 y Clang 16. |
nehalem |
Intel Nehalem con soporte
de instrucciones MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, POPCNT y
extensiones 64-bit. Esta opción está disponible a
partir de GCC 4.9. |
nocona |
Versión mejorada de Intel Pentium4 con soporte de instrucciones MMX, SSE, SSE2, SSE3 y extensiones 64-bit. |
pantherlake |
Intel
Panther Lake con soporte de instrucciones MOVBE, MMX, SSE, SSE2, SSE3,
SSSE3, SSE4.1, SSE4.2, POPCNT, AES, PREFETCHW, PCLMUL, RDRND, XSAVE,
XSAVEC, XSAVES, XSAVEOPT, FSGSBASE, PTWRITE, RDPID, SGX, GFNI-SSE,
CLWB, MOVDIRI, MOVDIR64B, CLDEMOTE, WAITPKG, ADCX, AVX, AVX2, BMI,
BMI2, F16C, FMA, LZCNT, PCONFIG, PKU, VAES, VPCLMULQDQ, SERIALIZE,
HRESET, KL, WIDEKL, AVX-VNNI, UINTR, AVXIFMA, AVXVNNIINT8,
AVXNECONVERT, CMPCCXADD, AVXVNNIINT16, SHA512, SM3, SM4, PREFETCHI y
extensiones 64-bit. Esta opción está disponible a partir
de GCC 14 y Clang 18. |
penryn |
Intel Penryn con soporte de instrucciones MMX, SSE, SSE2, SSE3, SSSE3 y SSE4.1. |
pentiumpro |
Intel PentiumPro. |
pentium2 |
Intel Pentium2 basado en PentiumPro con soporte de instrucciones MMX. |
pentium3, pentium3m |
Intel Pentium3 basado en PentiumPro con soporte de instrucciones MMX y SSE. |
pentium4, pentium4m |
Intel Pentium4 con soporte de instrucciones MMX, SSE y SSE2. |
pentium-m |
Versión de bajo
consumo de Intel Pentium3 con soporte de instrucciones MMX, SSE y SSE2.
Utilizado por los portátiles Centrino. |
pentium-mmx |
Intel PentiumMMX basado en Pentium con soporte de instrucciones MMX. |
prescott |
Versión mejorada de Intel Pentium4 con soporte de instrucciones MMX, SSE, SSE2 y SSE3. |
raptorlake |
Intel Raptor Lake. Esta opción está disponible a partir de GCC 13 y Clang 16. |
rocketlake |
Intel Rocket Lake con
soporte de instrucciones x86-64 (MOVBE, MMX, SSE, SSE2, SSE3, SSSE3,
SSE4.1, SSE4.2, POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND,
FMA, BMI, BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC,
XSAVES, AVX512F, AVX512VL, AVX512BW, AVX512DQ, AVX512CD, AVX512VBMI,
AVX512IFMA, SHA, CLWB, UMIP, RDPID, GFNI, AVX512VBMI2, AVX512VPOPCNTDQ,
AVX512BITALG, AVX512VNNI, VPCLMULQDQ, VAES) y extensiones 64-bit. Esta
opción está disponible a partir de GCC 11 y Clang 13. |
sandybridge |
Intel Sandy Bridge con
soporte de instrucciones MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2,
POPCNT, AVX, AES, PCLMUL y extensiones 64-bit. Esta opción
está disponible a partir de GCC 4.9 y Clang 3.6. |
sapphirerapids |
Intel Sapphire Rapids
con soporte de instrucciones x86-64 (MOVBE, MMX, SSE, SSE2, SSE3,
SSSE3, SSE4.1, SSE4.2, POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE,
RDRND, FMA, BMI, BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT,
XSAVEC, XSAVES, AVX512F, CLWB, AVX512VL, AVX512BW, AVX512DQ, AVX512CD,
AVX512VNNI, AVX512BF16, MOVDIRI, MOVDIR64B, AVX512VP2INTERSECT, ENQCMD,
CLDEMOTE, PTWRITE, WAITPKG, SERIALIZE, TSXLDTRK, UINTR, AMX-BF16,
AMX-TILE, AMX-INT8, AVX-VNNI) y extensiones 64-bit. Esta opción
está disponible a partir de GCC 11 y Clang 12. |
silvermont |
Intel Silvermont con
soporte de instrucciones MOVBE, MMX, SSE, MOVBE, MMX, SSE, SSE2, SSE3,
SSSE3, SSE4.1, SSE4.2, POPCNT, AES, PCLMU, RDRND y extensiones
64-bit. Esta opción está disponible a partir de GCC 4.9 y Clang 3.6. |
sierraforest |
Intel Sierra Forest con
soporte de instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1,
SSE4.2, POPCNT, AES, PREFETCHW, PCLMUL, RDRND, XSAVE, XSAVEC, XSAVES,
XSAVEOPT, FSGSBASE, PTWRITE, RDPID, SGX, GFNI-SSE, CLWB, MOVDIRI,
MOVDIR64B, CLDEMOTE, WAITPKG, ADCX, AVX, AVX2, BMI, BMI2, F16C, FMA,
LZCNT, PCONFIG, PKU, VAES, VPCLMULQDQ, SERIALIZE, HRESET, KL, WIDEKL,
AVX-VNNI, AVXIFMA, AVXVNNIINT8, AVXNECONVERT, CMPCCXADD y extensiones
64-bit. Esta opción está disponible a partir de GCC 13 y Clang 16. |
skylake |
Intel Skylake
con soporte de instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3,
SSE4.1, SSE4.2, POPCNT, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA,
BMI, BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC, XSAVES y
extensiones 64-bit. Esta opción está disponible a partir
de GCC 6 y Clang 3.6. |
skylake-avx512 |
Intel Skylake Server
con soporte de instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3,
SSE4.1, SSE4.2, POPCNT, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA,
BMI, BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC, XSAVES,
AVX512F, AVX512VL, AVX512BW, AVX512DQ, AVX512CD y extensiones 64-bit.
Esta opción está disponible a partir de GCC 6 y Clang 3.9. |
tigerlake |
Intel
Tiger Lake con soporte de instrucciones OVBE, MMX, SSE, SSE2, SSE3,
SSSE3, SSE4.1, SSE4.2, POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE,
RDRND, FMA, BMI, BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT,
XSAVEC, XSAVES, AVX512F, AVX512VL, AVX512BW, AVX512DQ, AVX512CD,
AVX512VBMI, AVX512IFMA, SHA, CLWB, UMIP, RDPID, GFNI, AVX512VBMI2,
AVX512VPOPCNTDQ, AVX512BITALG, AVX512VNNI, VPCLMULQDQ, VAES, PCONFIG,
WBNOINVD, MOVDIRI, MOVDIR64B, AVX512VP2INTERSECT y extensiones 64-bit.
Esta opción está disponible a partir de GCC 10 y Clang 10. |
tremont |
Intel Tremont con soporte
de instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2,
POPCNT, AES, PCLMUL, RDRND, XSAVE, XSAVEOPT, FSGSBASE, PTWRITE, RDPID,
SGX, UMIP, GFNI-SSE, CLWB, ENCLV y extensiones 64-bit. Esta
opción está disponible a partir de GCC 9 y Clang 7. |
westmere |
Intel Westmere con soporte
de instrucciones MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, POPCNT,
AES, PCLMUL y extensiones 64-bit. Esta opción está
disponible a partir de GCC 4.9. |
yonah |
Procesadores basados en la microarquitectura de Pentium M, con soporte de instrucciones MMX, SSE, SSE2 y SSE3. |
AMD |
amdfam10, barcelona |
Procesadores basados en
AMD Family 10h core con soporte de instrucciones x86-64 (MMX, SSE,
SSE2, SSE3, SSE4A, 3DNow!, enhanced 3DNow!, ABM y extensiones
64-bit). Esta opción está disponible a partir de GCC 4.3. La definición barcelona está disponible a partir de Clang 3.6. |
athlon, athlon-tbird |
AMD Athlon con soporte de instrucciones MMX, 3DNow!, enhanced 3DNow! y SSE prefetch. |
athlon4, athlon-xp, athlon-mp |
Versiones mejoradas de AMD Athlon con soporte de instrucciones MMX, 3DNow!, enhanced 3DNow! y full SSE. |
bdver1 |
Procesadores basados en
AMD Family 15h core con soporte de instrucciones x86-64 (FMA4, AVX,
XOP, LWP, AES, PCL_MUL, CX16, MMX, SSE, SSE2, SSE3, SSE4A, SSSE3,
SSE4.1, SSE4.2, ABM y extensiones 64-bit). Esta opción
está disponible a partir de GCC 4.7. |
bdver2 |
Procesadores basados en
AMD Family 15h core con soporte de instrucciones x86-64 (BMI, TBM,
F16C, FMA, LWP, AVX, XOP, LWP, AES, PCL_MUL, CX16, MMX, SSE, SSE2,
SSE3, SSE4A, SSSE3, SSE4.1, SSE4.2, ABM y extensiones
64-bit). Esta opción está disponible a partir de GCC 4.7. |
bdver3 |
Procesadores basados en
AMD Family 15h core con soporte de instrucciones x86-64 (FMA4, AVX,
XOP, LWP, AES, PCL_MUL, CX16, MMX, SSE, SSE2, SSE3, SSE4A, SSSE3,
SSE4.1, SSE4.2, ABM y extensiones 64-bit). Esta opción
está disponible a partir de GCC 4.8 y Clang 3.4. |
bdver4 |
Procesadores basados en
AMD Family 15h core con soporte de instrucciones x86-64 (BMI, BMI2,
TBM, F16C, FMA, FMA4, FSGSBASE, AVX, AVX2, XOP, LWP, AES, PCL_MUL,
CX16, MOVBE, MMX, SSE, SSE2, SSE3, SSE4A, SSSE3, SSE4.1, SSE4.2, ABM y
extensiones 64-bit). Esta opción está disponible a partir
de GCC 4.9 y Clang 3.5. |
btver1 |
Procesadores basados en
AMD Family 14h core con soporte de instrucciones x86-64 (MMX, SSE,
SSE2, SSE3, SSE4A, CX16, ABM y extensiones 64-bit). Esta
opción está disponible a partir de GCC 4.6. |
btver2 |
Procesadores basados en
AMD Family 16h core con soporte de instrucciones x86-64 (MOVBE, F16C,
BMI, AVX, PCL_MUL, AES, SSE4.2, SSE4.1, CX16, ABM, SSE4A, SSSE3, SSE3,
SSE2, SSE, MMX y extensiones 64-bit). Esta opción
está disponible a partir de GCC 4.8. |
geode |
AMD integrado con soporte de instrucciones MMX y 3DNow!. Esta opción está disponible a partir de GCC 4.3. |
k6 |
AMD K6 con soporte de instrucciones MMX. |
k6-2, k6-3 |
Versiones mejoradas de AMD K6 con soporte de instrucciones MMX y 3DNow!. |
k8, opteron, athlon64, athlon-fx |
Procesadores basados en
AMD K8 core con soporte de instrucciones x86-64 (MMX, SSE, SSE2,
3DNow!, enhanced 3DNow! y extensiones 64-bit). |
k8-sse3, opteron-sse3, athlon64-sse3 |
Versiones mejoradas de AMD
K8 core con soporte de instrucciones SSE3. Esta opción
está disponible a partir de GCC 4.3. |
znver1 |
Procesadores basados en
AMD Family 17h core con soporte de instrucciones x86-64 (BMI, BMI2,
F16C, FMA, FSGSBASE, AVX, AVX2, ADCX, RDSEED, MWAITX, SHA, CLZERO, AES,
PCL_MUL, CX16, MOVBE, MMX, SSE, SSE2, SSE3, SSE4A, SSSE3, SSE4.1,
SSE4.2, ABM, XSAVEC, XSAVES, CLFLUSHOPT, POPCNT y extensiones
64-bit). Esta opción está disponible a partir de GCC 6 y Clang 4. |
znver2 |
Procesadores basados en
AMD Family 17h core con soporte de instrucciones x86-64 (BMI, BMI2,
,CLWB, F16C, FMA, FSGSBASE, AVX, AVX2, ADCX, RDSEED, MWAITX, SHA,
CLZERO, AES, PCL_MUL, CX16, MOVBE, MMX, SSE, SSE2, SSE3, SSE4A, SSSE3,
SSE4.1, SSE4.2, ABM, XSAVEC, XSAVES, CLFLUSHOPT, POPCNT y
extensiones 64-bit). Esta opción está disponible a
partir de GCC 9 y Clang 9. |
znver3 |
Procesadores basados en
AMD Family 19h core con soporte de instrucciones x86-64 (BMI, BMI2,
CLWB, F16C, FMA, FSGSBASE, AVX, AVX2, ADCX, RDSEED, MWAITX, SHA,
CLZERO, AES, PCLMUL, CX16, MOVBE, MMX, SSE, SSE2, SSE3, SSE4A, SSSE3,
SSE4.1, SSE4.2, ABM, XSAVEC, XSAVES, CLFLUSHOPT, POPCNT, RDPID,
WBNOINVD, PKU, VPCLMULQDQ, VAES) y extensiones 64-bit. Esta
opción está disponible a partir de GCC 11 y Clang 12. |
znver4 |
Procesadores basados en
AMD Family 19h core con soporte de instrucciones x86-64 (BMI, BMI2,
CLWB, F16C, FMA, FSGSBASE, AVX, AVX2, ADCX, RDSEED, MWAITX, SHA,
CLZERO, AES, PCLMUL, CX16, MOVBE, MMX, SSE, SSE2, SSE3, SSE4A, SSSE3,
SSE4.1, SSE4.2, ABM, XSAVEC, XSAVES, CLFLUSHOPT, POPCNT, RDPID,
WBNOINVD, PKU, VPCLMULQDQ, VAES, AVX512F, AVX512DQ, AVX512IFMA,
AVX512CD, AVX512BW, AVX512VL, AVX512BF16, AVX512VBMI, AVX512VBMI2,
AVX512VNNI, AVX512BITALG, AVX512VPOPCNTDQ, GFNI) y extensiones 64-bit.
Esta opción está disponible a partir de GCC 12.3 y Clang 16. |
znver5 |
Procesadores basados en
AMD Family 1ah core con soporte de instrucciones x86-64 (BMI, BMI2,
CLWB, F16C, FMA, FSGSBASE, AVX, AVX2, ADCX, RDSEED, MWAITX, SHA,
CLZERO, AES, PCLMUL, CX16, MOVBE, MMX, SSE, SSE2, SSE3, SSE4A, SSSE3,
SSE4.1, SSE4.2, ABM, XSAVEC, XSAVES, CLFLUSHOPT, POPCNT, RDPID,
WBNOINVD, PKU, VPCLMULQDQ, VAES, AVX512F, AVX512DQ, AVX512IFMA,
AVX512CD, AVX512BW, AVX512VL, AVX512BF16, AVX512VBMI, AVX512VBMI2,
AVX512VNNI, AVX512BITALG, AVX512VPOPCNTDQ, GFNI, AVXVNNI, MOVDIRI,
MOVDIR64B, AVX512VP2INTERSECT, PREFETCHI) y extensiones 64-bit. Esta
opción está disponible a partir de GCC 14. |
Niveles de optimización soportados por Clang
Niveles de optimización soportados por Clang
|
-O0
|
Sin optimizaciones. Es el nivel más rápido para compilar programas y genera el código más depurable.
|
-O1
|
Un nivel intermedio entre -O0 y -O2.
|
-O2 |
Un nivel moderado de optimización.
|
-O3
|
Lo mismo que -O2,
excepto que permite optimizaciones que alargan el proceso de
compilación y pueden llegar a generar un binario de
tamaño más grande, con la idea de hacer que se ejecute
más rápido.
|
-Os
|
Lo mismo que -O2, con optimizaciones adicionales para reducir el tamaño del binario resultante.
|
-Oz |
Lo mismo que -Os, pero con una reducción de tamaño del binario resultante, más agresiva.
|
-O
|
Equivalente a -O2.
|
-O4 y superiores
|
Actualmente equivale a -O3.
|
-Og |
Equivalente a -O1. |
Optimizaciones adicionales para Clang
Optimizaciones adicionales para Clang
|
Polly |
-mllvm -polly |
Activa el uso de Polly, un optimizador de características similares a la optimización Graphite de GCC.
Este optimizador solo funciona en el nivel '-O3' de
optimización. Puede provocar errores de compilación
y de ejecución en determinados paquetes.
La definición de la optimización Graphite también es válida para Polly y consiste en utilizar la representación de la figura geométrica del poliedro
para ejecutar en paralelo los bucles de programación que
contenga el código fuente de un programa, en el binario
resultante del proceso de compilación, acelerando de forma
considerable el tiempo de ejecución del mismo. |
-mllvm -polly-vectorizer=stripmine |
Activa la generación automática de código vectorizado, a través de Polly. Este parámetro debe ir precedido del anterior. Desde Clang 3.5 es el parámetro predefinido de Polly utilizado en los manuales de la web. A partir de la versión 3.7, se ha sustituido el valor polly por stripmine. El primer valor se ha eliminado a partir de Clang 17.
|
-mllvm -polly-parallel |
Activa la generación automática de código OpenMP, a través de Polly.
Este parámetro debe ir precedido del inicial de esta
sección. Este parámetro lo pongo como experimental, y
sólo lo podremos aplicar en aquellos paquetes que contengan
código OpenMP, en combinación con el utilizado por el compilador para dicho proceso. |
-mllvm-polly-omp-backend=LLVM |
Activa que Polly utilice libomp en lugar de libgomp (GNU) que es la predefinida, para generar el código OpenMP. |
-mllvm -polly-position=before-vectorizer |
Activa que Polly
se ejecute antes que LLVM en el proceso de optimización y no
después, que es el modo de trabajar predefinido. Este
parámetro debe ir precedido del inicial de esta sección.
En determinados procesos de compilación puede mejorar la
optimización del binario resultante. En otros la puede empeorar.
Más información en este enlace.
|
-mllvm -polly-2nd-level-tiling |
Activa un segundo nivel de
optimización de mosaico de bucle. Por defecto, Polly tiene
activada la optimización de mosaico (tiling). Con esta
opción hacemos que le dé otra pasada más profunda
de este tipo de optimización específico, al código
a compilar. |
-mllvm -polly-pattern-matching-based-opts |
Activa optimizaciones basadas en patrones idénticos. |
-mllvm -polly-loop-fusion-greedy |
Intenta fusionar de forma agresiva
todos los bucles de programación, independientemente del
rendimiento que pueda producir. Esta opción está disponible a partir
de la versión 14 de Polly. |
LTO |
-flto |
Activa la optimización LTO, equivalente a la optimización LTO de GCC.
Puede provocar errores de compilación y de ejecución en
determinados paquetes. Tenemos que tener instalado y configurado el
paquete Binutils, con el enlazador dinámico ld.gold como el predefinido del sistema, para que este parámetro sea funcional. La otra alternativa es utilizar LLD como enlazador dinámico.
Además de haber compilado el plugin LLVM Gold
como se explica en este manual. La carga de este plugin se realiza de
forma automática, sin tener que añadir ningún
parámetro adicional.
En procesos de compilación que se generen librerías estáticas, o que intervenga el programa nm de Binutils, tendremos que establecer la siguiente variable de entorno, antes de ejecutar el script de configuración del paquete.
$ export AR=llvm-ar RANLIB=llvm-ranlib NM=llvm-nm |
En el manual de GCC
explico de forma más extendida el porqué del uso de esta
variable de entorno, en la sección de preguntas y respuestas
relacionada con la optimización LTO.
|
ThinLTO |
-flto=thin |
ThinLTO
es una variante más agresiva de LTO, introducida a partir de la
versión 3.9 de LLVM. Lo que se busca con esta
optimización es reducir a la mínima expresión el
tiempo necesario para generar el binario ejecutable correspondiente a
partir de los archivos objeto que intervengan en el proceso de enlace,
aprovechando la capacidad multinúcleo de los procesadores
actuales, que es el principal inconveniente que se nos presenta cuando
hacemos uso de la tradicional optimización LTO. Podemos
encontrar más información y la correspondiente
comparativa en esta entrada del blog de la web de LLVM.
A diferencia de LTO que utiliza sólo un archivo objeto para
volcar el proceso de enlazado, ThinLTO divide el mismo en
múltiples archivos objeto, lo que puede llegar a rebasar el
límite de procesos por usuario establecidos en nuestro sistema,
impidiendo por ejemplo, si tenemos un limite de 1024, que en paquetes
como Inkscape o GTK3, no podamos utilizar esta optimización.
Para solucionar este inconveniente, primero comprobaremos el
límite de procesos por usuario que tenemos en nuestro sistema
con el siguiente comando:
[jose@localhost ~]$ ulimit -n
1024 |
En mi caso personal son 1024, que elevo a 4096, con el mismo comando al que le añado el número dado.
Como este valor es volátil y desaparece cuando reiniciamos el
sistema, creamos el script correspondiente para que dicho valor quede
establecido por defecto al inicio del sistema. Abrimos un editor de
texto y añadimos lo siguiente:
Lo guardamos con el nombre ulimit.sh y lo instalamos en /etc/profile.d.
$ su -c "install -m755 ulimit.sh /etc/profile.d" |
En el siguiente reinicio del sistema, comprobamos que el valor establecido por el script es el que está en uso.
[jose@localhost ~]$ ulimit -n
4096 |
|
Unified LTO |
-funified-lto
-Wl,--lto=full o thin |
A partir de Clang 17, se
introduce esta opción de compilación, que permite
combinar una optimación LTO o ThinLTO en el proceso previo al
enlazado, con una optimización LTO o ThinLTO, en el posterior
enlazado con LLD. Podemos encontrar más información en
este enlace.
La aplicación real de la misma sirve para reducir el tiempo de
compilación de una optimización LTO, al introducir la
posibilidad de aplicar una optimización ThinLTO en el proceso de
enlazado con LLD, al unificar el código LTO en una sóla
estructura compatible con las dos optimizaciones. Si lo hacemos a la
inversa, compilar con ThinLTO y enlazar con LTO, los tiempos de
compilación se disparan de forma exponencial.
Un ejemplo con LTO+ThinLTO de variable de entorno a establecer sería este:
$ export {C,CXX}FLAGS+=" -flto -funified-lto"
$ export LDFLAGS+=" -Wl,--lto=thin"
|
Y viceversa,
$ export {C,CXX}FLAGS+=" -flto=thin -funified-lto"
$ export LDFLAGS+=" -Wl,--lto=full"
|
Las optimizaciones adicionales LTO y ThinLTO para LLD, siguen siendo
igual de aplicables, en función del tipo de optimización
que elijamos a utilizar por el enlazador.
|
OpenMP |
-fopenmp=libomp
|
OpenMP
es una API de programación creada única y exclusivamente
para aprovechar la potencia de los procesadores multinúcleo, si
el nuestro no lo es, no es necesario seguir leyendo esto. Esta
optimización sólo es operativa en aquellos paquetes de
código fuente que están previamente preparados para
utilizarla: ImageMagick, Blender, Inkscape, etc.
La versión actual de Clang es compatible con la
versión 5.1 de OpenMP e inferiores. El parámetro a
añadir varía del utilizado por GCC, y permite elegir
qué librería utilizar para el enlazado del binario
ejecutable. Si no especificamos ninguna y dejamos que el script de
configuración del paquete detecte el parámetro -fopenmp,
el mismo se enlazará contra la librería libomp de LLVM.
En versiones antiguas de Clang, se enlaza por defecto contra la
librería libgomp de GCC.
Desde la versión 3.9 de Clang, también se puede
seleccionar la versión de OpenMP a utilizar por el compilador,
en el caso de que el script de configuración del paquete, no
detecte de forma correcta la versión más reciente. En
este caso el parámetro a añadir al inicial, sería
uno de los siguientes:
-fopenmp-version=31 >> OpenMP 3.1
-fopenmp-version=40 >> OpenMP 4.0
-fopenmp-version=45 >> OpenMP 4.5 (versión predefinida de Clang 10 si sólo se utiliza el parámetro -fopenmp)
-fopenmp-version=50
>> OpenMP 5.0 (a partir de Clang 10. Versión
predefinida de Clang 11 si sólo se utiliza el
parámetro -fopenmp)
-fopenmp-version=51 >> OpenMP 5.1 (a partir de Clang 11. Versión
predefinida de Clang 17 si sólo se utiliza el
parámetro -fopenmp)
Que quedaría así en una variable de entorno, un ejemplo con OpenMP 4.5:
$ export {C,CXX}FLAGS+=" -fopenmp=libomp -fopenmp-version=45"
|
Es posible que en algunos procesos tengamos que añadir una variable de entorno LDFLAGS, tipo export LDFLAGS+=' -lomp'
para que la librería de OpenMP proporcionada por LLVM intervenga
en el proceso de enlazado. En paquetes como ImageMagick es necesario
hacer una sustitución masiva después de ejecutar el
script de configuración para sustituir el parámetro -lgomp, añadido de forma automática por el script de configuración, por el parámetro -lomp. Un ejemplo:
$ find . -name 'Makefile' -type f | xargs sed -i 's:-lgomp:-lomp:g' |
Como experiencia personal con algunos paquetes, mi recomendación
es que se utilicen los siguientes parámetros para el uso de esta
optimización.
$ export {C,CXX}FLAGS+=" -fopenmp=libomp -fopenmp-version=51"
$ export LDFLAGS+=" -lomp"
|
En paquetes como LibRaw, si dejamos que el script de
configuración establezca el parámetro -fopenmp por
sí mismo, nos encontraremos que, la librería resultante
del proceso de compilación, no quedará enlazada contra
libomp y, por lo tanto, no hará uso de las
características de esta optimización. En cambio, en otros
paquetes como MAME, sí que funciona este parámetro sin
que tengamos que añadir nada por nuestra cuenta.
|
PGO |
-fprofile-generate=ruta a directorio o archivo
-fprofile-use=ruta a directorio o archivo |
PGO son las siglas con las que se conoce a la optimización Profile Guided Optimization (Optimización
Guiada por Perfiles). El compilador recopila información
del total de funciones y bloques de datos que contiene el binario
ejecutable, tanto en el proceso de compilación como en una
posterior ejecución del mismo. Dichos datos serán
utilizados en un segundo proceso de compilación, pudiendo
utilizarlos en posteriores procesos de compilación, siempre y
cuando, el código fuente no sea alterado de forma significativa.
La optimización PGO se divide en dos modos:
instrumentación (la que explico aquí) y muestreo, que
requiere del uso de aplicaciones externas como Perf y AutoFDO,
realizando todo el proceso de forma manual por parte del usuario:
ejecución del binario compilado con perf para obtener las
muestras y su posterior conversión con AutoFDO a un formato
legible por Clang.
A diferencia de las otras optimizaciones explicadas en este manual,
ésta requiere de un proceso más elaborado para su
aplicación, que explico a continuación:
1) Creamos un directorio de ubicación de los perfiles de
optimización guiada con permisos de escritura para todos los
usuarios.
$ su
# mkdir -p /var/pgo
# chmod 777 /var/pgo |
2) Establecemos la variable de entorno de generación del perfil
de optimización con la ruta del directorio de perfiles de
optimización que hemos creado, más el nombre del
paquete que vamos a compilar, por ejemplo, mc. Añadimos un nivel
de optimización -O2 y un parámetro de generación de símbolos de depuración, g1 o -gline-tables-only que es lo mismo.
$ export {C,CXX}FLAGS+=' -O2 -g1 -fprofile-generate=/var/pgo/mc |
3) Ejecutamos el script de configuración pertinente y compilamos
el paquete. En la ruta indicada se habrán creado una serie de
archivos de datos con el nombre default_*.profraw.
Instalamos el paquete y lo ejecutamos. Si el paquete de código
fuente contiene tests, lo mejor para recopilar información es
ejecutar en el mismo make check después
de haber compilado el mismo (nos ahorramos tener que instalarlo). En
unos paquetes esto resulta efectivo (por ejemplo, ImageMagick o POV-Ray), en otros, al ser los tests muy básicos, lo mejor es ejecutar la aplicación.
4) Convertimos el formato en crudo de los archivos default_*.profraw a un formato binario legible por Clang, con el comando llvm-profdata:
$ llvm-profdata merge /var/pgo/mc/default_*.profraw \
--output=/var/pgo/mc/default.profdata |
Con la variable de entorno LLVM_PROFILE_FILE, podemos cambiar la ruta
predefinida de ubicación y el nombre del perfil de
optimización. Un ejemplo de ejecución de un programa, en
el que se sustituye el nombre predefinido, por la ID del proceso de
ejecución. Esto nos permitirá crear varios archivos de
perfil por ejecución del programa, que podremos combinar con el
comando llvm-profdata, para su posterior uso en el segundo proceso de compilación del paquete:
$ LLVM_PROFILE_FILE=/var/pgo/mc/mc-%p.profraw mc |
$ llvm-profdata merge /var/pgo/mc/mc-*.profraw \
--output=/var/pgo/mc/default.profdata |
5) Volvemos a recompilar el paquete. Tenemos dos opciones, una es
empezar de cero con las variables de entorno y añadir la
siguiente, volviendo a ejecutar el script de configuración,
después de haber limpiado el directorio de compilación
con el comando make distclean o make clean según esté configurado:
$ export {C,CXX}FLAGS+=' -fprofile-use=/var/pgo/mc |
La otra más rápida consiste en modificar los archivos
Makefile de forma masiva, modificando el parámetro aplicado, con
el siguiente comando:
$ find . -name 'Makefile' | xargs sed -i 's:fprofile-generate:fprofile-use:g' |
Una vez los hayamos modificado, ejecutamos make clean; make y volvemos a instalar el paquete. El
perfil de optimización creado lo podemos cargar de forma directa
en la siguiente compilación, siempre y cuando el código
fuente no haya sido alterado de forma significativa. Ya se
encargará el compilador de avisarnos de esto. Si tenemos
desactivados los avisos con el parámetro -w, no nos
avisará en absoluto.
Tener en cuenta que si creamos el perfil con el parámetro -O2 -g1,
sin ningún tipo de optimización adicional,
obtendremos más información que nos servirá para
aplicar una optimización PGO más efectiva. Lo cual no
quiere decir que no se pueda realizar el proceso con las mismas
optimizaciones en el comienzo y en el final del mismo.
$ export {C,CXX}FLAGS+=' -fprofile-use=/var/pgo/mc |
Para acelerar todo esto, siempre es bueno crearse unas funciones de
Bash. Abrimos con un editor de texto, el archivo ~/.bashrc, si no
existe lo creamos y añadimos lo siguiente al final del mismo:
optclang-gpgo () { dir="$1"; export {C,CXX}FLAGS+=" -O2 -g1 -fprofile-generate=/var/pgo/$dir"; }
optclang-upgo () { dir="$1"; export {C,CXX}FLAGS+=" -fprofile-use=/var/pgo/$dir"; }
optclang-profdata () {
llvm-profdata merge /var/pgo/$1/default_*.profraw
--output=/var/pgo/$1/default.profdata; rm -f
/var/pgo/$1/default_*.profraw; }
|
Guardamos el archivo, abrimos una ventana de terminal, y ahora
simplemente basta ejecutar el alias correspondiente para añadir
la variable de entorno de esta optimización más el nombre
del directorio que definamos para ubicar los datos del perfil.
Primer proceso de compilación:
Conversión de los datos del perfil (incluye borrado de los
archivos generados por el compilador para reducir el espacio en disco
de los directorios que incluyen los perfiles de optimización)
Segundo proceso de compilación:
Y, por último, siempre que se modifiquen los parámetros
de optimización, se debe de crear un perfil nuevo de
optimización porque los resultados pueden variar
significativamente en función de las optimizaciones aplicadas en
el proceso de compilación.
|
CSPGO |
-fprofile-use=ruta a directorio o archivo -fcs-profile-generate=ruta a directorio o archivo
-fprofile-use=ruta a archivo |
Introducida a partir de Clang 9, CSPGO
es una optimización PGO de dos pases, primero se realiza una PGO
normal y, a partir del archivo de perfil creado se vuelve a recompilar
el paquete tomando como referencia dicho archivo, para finalmente,
volver a recompilar el paquete con el archivo de perfil PGO resultante
de la fusión de los archivos de perfil en crudo generados por el
ejecutable (default_*.profraw) y el perfil PGO inicial
(default.profdata). Un ejemplo:
1) Primer proceso de compilación tomando como referencia el archivo de perfil PGO creado en la sección anterior:
$ export {C,CXX}FLAGS+=' -O2 -g1 -fprofile-use=/var/pgo/mc -fcs-profile-generate=/var/pgo/mc |
2) Ejecución y testeo del programa.
3) Convertimos el formato en crudo de los archivos default_*.profraw a un formato binario legible por Clang, con el comando llvm-profdata,
mezclándolos con el perfil PGO creado inicialmente, creando un
archivo de perfil de salida con el nombre de la optimización:
$ llvm-profdata merge /var/pgo/mc/default_*.profraw \
/var/pgo/mc/default.profdata --output=/var/pgo/mc/cspgo.profdata |
4) Finalmente, utilizamos el perfil resultante de la fusión, en el proceso de compilación:
$ export {C,CXX}FLAGS+=' -fprofile-use=/var/pgo/mc/cspgo.profdata |
Para acelerar todo esto, siempre es bueno crearse unas funciones de
Bash. Abrimos con un editor de texto, el archivo ~/.bashrc, si no
existe lo creamos y añadimos lo siguiente al final del mismo:
optclang-csgpgo () { dir="$1"; export {C,CXX}FLAGS+=" -O2 -g1 -fprofile-use=/var/pgo/$dir -fcs-profile-generate=/var/pgo/$dir"; }
optclang-csupgo () { dir="$1"; export {C,CXX}FLAGS+=" -fprofile-use=/var/pgo/$dir/cspgo.profdata"; }
optclang-csprofdata () { llvm-profdata merge /var/pgo/$1/default.profdata /var/pgo/$1/default_*.profraw --output=/var/pgo/$1/cspgo.profdata; rm -f /var/pgo/$1/default_*.profraw; }
|
Guardamos el archivo, abrimos una ventana de terminal, y ahora
simplemente basta ejecutar el alias correspondiente para añadir
la variable de entorno de esta optimización más el nombre
del directorio que definamos para ubicar los datos del perfil.
Primer proceso de compilación:
Conversión de los datos del perfil (incluye borrado de los
archivos generados por el compilador para reducir el espacio en disco
de los directorios que incluyen los perfiles de optimización) y
mezcla con el archivo de perfil PGO. Como opción también
le podemos añadir que borre el archivo de perfil PGO
(default.profdata), para dejar solo el archivo de perfil CSPGO
(cspgo.profdata).
Segundo proceso de compilación:
Por último, si se producieran mensajes de error en la ejecución y testeo del programa, del tipo error: undefined reference to '__llvm_profile_runtime', añadimos la siguiente variable de entorno LDFLAGS en el primer proceso de compilación:
$ export LDFLAGS+=" $(clang -print-resource-dir)/lib/x86_64-unknown-linux-gnu/libclang_rt.profile.a" |
Esto es válido también para la optimización PGO.
|
Para añadir estas optimizaciones adicionales a las variables de
entorno de optimización de CPU que hayamos establecido, basta
ejecutar el comando siguiente, incluyendo el nivel de
optimización nuevamente, para asegurarnos de que se utilice el
mismo en el proceso de compilación:
Polly
$ export {C,CXX}FLAGS+=' -O3 -mllvm -polly' |
Polly (generación automática de código vectorizado)
$ export {C,CXX}FLAGS+=' -O3 -mllvm -polly -mllvm -polly-vectorizer=stripmine' |
Polly (sólo en aquellos paquetes en los que se active por defecto el parámetro -fopenmp)
$ export {C,CXX}FLAGS+=' -O3 -mllvm -polly -mllvm -polly-vectorizer=stripmine -mllvm -polly-parallel' |
LTO
$ export {C,CXX}FLAGS+=' -flto'
|
ThinLTO
$ export {C,CXX}FLAGS+=' -flto=thin'
|
En algunos procesos hay que añadir también el parámetro a la variable de entorno LDFLAGS.
$ export {C,CXX,LD}FLAGS+=' -flto=thin'
|
En procesos que se generen librerías estáticas, o intervenga el comando nm de Binutils,
la variable de entorno sería la siguiente, acompañada de
la modificación que sea necesario realizar en paquetes que no
acepten estas variables de entorno.
$ export AR=llvm-ar RANLIB=llvm-ranlib NM=llvm-nm
$ export {C,CXX}FLAGS+=' -flto'
|
Tener en cuenta que el nivel de optimización aplicado en un
proceso de compilación es siempre el último que aparece
en la salida del compilador. Si el script de configuración del
paquete, incluye su propio nivel de optimización, es posible, y
en esta web hay ejemplos, de que éste se muestre detrás
del nivel de optimización que hayamos establecido mediante la
correspondiente variable de entorno en la terminal. Para evitar esto,
tendríamos que recurrir a una edición masiva de los
archivos 'Makefile', con el siguiente comando:
$ find . -name 'Makefile' | xargs sed -i 's:-O2::' |
Para ver las variables de entorno que hemos aplicado antes de ejecutar
el script de configuración, ejecutamos el siguiente comando:
$ echo ${CFLAGS,CXXFLAGS} |
Y si nos hemos equivocado en algo, pues las borramos y volvemos a
empezar. O las sobreescribimos volviendo a aplicar la primera variable
de entorno que hemos establecido, la que no lleva el símbolo '+'.
Clang suele mostrar más mensajes de aviso que GCC, Para
eliminarlos todos (algunos producen errores de compilación),
basta establecer la siguiente variable de entorno, antes de ejecutar el
proceso de configuración del paquete correspondiente.
$ export {C,CXX}FLAGS+=' -w' |
Crear alias de bash para facilitar las tareas de compilación de programas con Clang
Lo mejor que podemos hacer para no tener que estar copiando y pegando variables de entorno relacionadas con Clang,
es automatizar un poco el proceso, creando los correspondientes alias
de bash. A continuación pongo los míos, que cada usuarios
los adapte a sus necesidades. Abrimos con un editor de texto, el
archivo de configuración personal, ~/.bashrc, si no existe lo creamos, y añadimos lo siguiente al final del contenido del mismo:
alias optclang="export CC=clang CXX=clang++ {C,CXX}FLAGS='-O3 -march=znver3 -mtune=znver3 -mllvm -polly -mllvm -polly-vectorizer=stripmine'"
alias optclang-cpu="export CC=clang CXX=clang++ {C,CXX}FLAGS='-O3 -march=znver3 -mtune=znver3'"
alias optclang-lto="export {C,CXX}FLAGS+=' -flto'"
alias optclang--thinlto="export {C,CXX}FLAGS+=' -flto=thin'"
alias optclang-ar="export AR=llvm-ar RANLIB=llvm-ranlib NM=llvm-nm"
|
El principal es optclang,
que establece el uso de compilador, optimización de CPU y
optimización con Polly, en un sólo comando. Si nos falla
la compilación con Polly, sobreescribimos este alias con optclang-cpu, que omite la vectorización de código con Polly. Luego como añadido utilizamos el alias optclang-lto para utilizar la optimización LTO o la optimización ThinLTO con el alias optclang--thinlto, que combinamos con el alias optclang-ar
en procesos en los que se compilan librerías estáticas.
Tener en cuenta que todo esto debe de adaptarse al proceso de
compilación en cuestión. Muchas veces tenemos que
añadir el parámetro -flto
a la propia variable de entorno de uso de compilador (export
{CC,CXX}+=" -flto") para que esta optimización se pueda llevar a
cabo con algunos paquetes.
Con el nuevo soporte de OpenMP añadimos un nuevos alias, aunque su uso queda muy reducido por la escases de paquetes que soportan OpenMP.
alias optclang-omp="export {C,CXX}FLAGS+=' -fopenmp=libomp' LDFLAGS+=' -lomp'"
|
|