GCC tiene un atributo de función target_clones que se puede usar para crear diferentes versiones de una función que se compilan para usar diferentes conjuntos de instrucciones de tal manera que, cuando se ejecuta el binario, se selecciona la versión con el conjunto de instrucciones de más alto nivel para ejecutar .
Suponiendo que tengo algún fragmento de código que realiza muchas operaciones de punto flotante, puedo hacer que use el conjunto de instrucciones SIMD de más alto nivel escribiendo algo como esto:
__attribute__((target_clones("default", "sse", "sse2", "sse3", "ssse3", "sse4.1", "sse4.2", "avx", "avx2", "avx512"))) double my_ddot1(int n, double x[], double y[]) { double result = 0; for (int i = 0; i < n; i++) result += x[i] * y[i]; return result; }Pero eso implicó especificar manualmente todos los conjuntos de instrucciones posibles para los que quiero que se especialice.
Ahora, suponiendo que n sea grande, el código anterior es algo que evidentemente se ejecutará más rápido cuantas más operaciones se realicen a la vez, por lo que solo tiene que generar versiones para cada nivel SIMD (sse2/3/4, avx1/2). Puedo enumerar manualmente las disponibles para x64-64 y ponerlas en el atributo de función, pero en 10 años es probable que crezca el repertorio de opciones disponibles, por ejemplo, si se crea un "avx2048" más tarde, lo que evidentemente beneficiará a la función. siendo optimizado, el código anterior no lo seleccionará, sino que se atascará con "avx2".
¿Cómo puedo decirle a target_clones que compile para cada nivel SIMD sin tener que enumerarlos, de tal manera que la lista se actualice automáticamente según lo que admita el compilador?