alias de um modelo de função
Eu criei um distribuidor de CPU que compila as mesmas funções com diferentes opções de compilação em arquivos de objetos diferentes. Para que meu código acesse as mesmas funções em diferentes arquivos de objetos, preciso atribuir um nome diferente às funções de cada arquivo de objeto.
Em C (ou C ++), eu faria algo assim no arquivo de cabeçalho para as declarações da função.
typedef float MyFuncType(float a);
MyFuncType myfunc_SSE2, myfunc_SSE41, myfunc_AVX, myfunc_AVX2, myfunc_AVX512
Mas agora eu quero modelos de função para as declarações. Meu código real atualmente se parece mais com isso
//kernel.h
template <typename TYPE, unsigned N, typename VALUES>
void foo_SSE2(int32_t *buffer, VALUES & v);
template <typename TYPE, unsigned N, typename VALUES>
void foo_SSE41(int32_t *buffer, VALUES & v);
...
template <typename TYPE, unsigned N, typename VALUES>
void foo_AVX512(int32_t *buffer, VALUES & v);
#if INSTRSET == 2 // SSE2
#define FUNCNAME foo_SSE2
#elif INSTRSET == 5 // SSE4.1
#define FUNCNAME foo_SSE41
...
#if INSTRSET == 9 // AVX512
#define FUNCNAME foo_AVX512
#endif
Estas são apenas declarações em um arquivo de cabeçalho. As definições de função estão em um arquivo de origem separado, compilado em um arquivo de objeto diferente para cada nome de função. As definições são mais ou menos assim
//kernel.cpp
#include "kernel.h"
template<typename TYPE, unsigned N, typename VALUES>
void FUNCNAME(int32_t *buffer, VALUES & v) {
//code
}
Então eu compilo assim
gcc -c -O3 -msse2 kernel.cpp -o kernel_sse2.o
gcc -c -O3 -msse4.1 kernel.cpp -o kernel_sse41.o
...
gcc -c -O3 -mavx512f kernel.cpp -o kernel_avx512.o
gcc -O3 main.cpp kernel_sse2.o kernel_sse41.o ... kernel_avx512.o
O arquivomain.cpp
é outro arquivo de origem que precisa conhecer apenas as declarações de função para que o vinculador possa vinculá-las às definições nos outros arquivos de objeto. Se parece com isso
void dispatch(void) {
int iset = instrset_detect();
if (iset >= 9) {
fp_float1 = &foo_AVX512<float,1>;
}
else if (iset >= 8) {
fp_float1 = &foo_AVX2<float,1>;
}
...
else if (iset >= 2) {
fp_float1 = &foo_SSE2<float,1>;
}
}
int main(void) {
dispatch();
fp_float1(buffer, values);
}
Mas no meu arquivo "kernel.h" é irritante (e propenso a erros) repetir isso para cada alteração no nome da função. Eu quero algo como o seguinte (que eu sei que não funciona).
template <typename TYPE, unsigned N, typename VALUES>
typedef void foo(int32_t *buffer, VALUES & v);
foo foo_SSE2, foo_SSE41, foo_SSE_AVX, foo_AVX2, foo_AVX512
Existe uma maneira ideal para isso que separa as declarações e definições e me permite renomear declarações de função de modelo idênticas?