alias einer Funktionsvorlage

Ich habe einen CPU-Dispatcher erstellt, der dieselben Funktionen mit unterschiedlichen Kompilierungsoptionen in unterschiedliche Objektdateien übersetzt. Damit mein Code auf die gleichen Funktionen in verschiedenen Objektdateien zugreifen kann, muss ich den Funktionen in jeder Objektdatei einen anderen Namen geben.

In C (oder C ++) würde ich so etwas in der Header-Datei für die Deklarationen der Funktion tun.

typedef float MyFuncType(float a);

MyFuncType  myfunc_SSE2, myfunc_SSE41, myfunc_AVX, myfunc_AVX2, myfunc_AVX512

Aber jetzt möchte ich Funktionsvorlagen für die Deklarationen. Mein echter Code sieht momentan eher so aus

//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

Dies sind nur Deklarationen in einer Header-Datei. Die Funktionsdefinitionen befinden sich in einer separaten Quelldatei, die für jeden Funktionsnamen in eine andere Objektdatei kompiliert wird. Die Definitionen sehen ungefähr so aus

//kernel.cpp
#include "kernel.h"
template<typename TYPE, unsigned N, typename VALUES>
void FUNCNAME(int32_t *buffer, VALUES & v) {
    //code
}

Dann kompiliere ich so

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

Die Dateimain.cpp ist eine weitere Quelldatei, die nur die Funktionsdeklarationen kennen muss, damit der Linker sie mit den Definitionen in den anderen Objektdateien verknüpfen kann. Es sieht aus wie da

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);
}

Aber in meiner Datei "kernel.h" ist es ärgerlich (und fehleranfällig), dies bei jeder Änderung des Funktionsnamens zu wiederholen. Ich möchte so etwas wie das Folgende (von dem ich weiß, dass es nicht funktioniert).

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

Gibt es dazu einen idealen Weg, der die Deklarationen und Definitionen voneinander trennt und es mir ermöglicht, identische Template-Funktionsdeklarationen einfach umzubenennen?

Antworten auf die Frage(2)

Ihre Antwort auf die Frage