Istnieje kilka rozwiązań.
Jedna jest oparta na C++, gdzie można utworzyć wiele klas - zazwyczaj implementuje się klasę interfejsu i wykorzystuje funkcję fabryczną, aby podać obiekt właściwej klasy.
np.
class Matrix
{
virtual void Multiply(Matrix &result, Matrix& a, Matrix &b) = 0;
...
};
class MatrixPlain : public Matrix
{
void Multiply(Matrix &result, Matrix& a, Matrix &b);
};
void MatrixPlain::Multiply(...)
{
... implementation goes here...
}
class MatrixSSE: public Matrix
{
void Multiply(Matrix &result, Matrix& a, Matrix &b);
}
void MatrixSSE::Multiply(...)
{
... implementation goes here...
}
... same thing for AVX...
Matrix* factory()
{
switch(type_of_math)
{
case PlainMath:
return new MatrixPlain;
case SSEMath:
return new MatrixSSE;
case AVXMath:
return new MatrixAVX;
default:
cerr << "Error, unknown type of math..." << endl;
return NULL;
}
}
Albo, jak zasugerowano powyżej, można użyć współdzielonych bibliotek, które mają wspólny interfejs i dynamicznie załadować bibliotekę, że ma rację.
Oczywiście, jeśli zaimplementujesz klasę bazową Matrix jako klasę "zwykłą", możesz dokonać stopniowego udoskonalenia, a implementacja tylko tych części, które faktycznie znajdziesz, będzie korzystna, i polegaj na klasie bazowej, aby zaimplementować funkcje, w których wydajność nie jest " t wysoce krwisty.
Edytuj: Mówisz o linii i myślę, że patrzysz na nieprawidłowy poziom funkcji, jeśli tak jest. Potrzebujesz dość dużych funkcji, które robią coś na całkiem sporo danych. W przeciwnym razie wszystkie twoje wysiłki zostaną poświęcone na przygotowanie danych we właściwym formacie, a następnie wykonanie kilku instrukcji obliczeniowych, a następnie włożenie danych z powrotem do pamięci.
Zastanowiłabym się również, w jaki sposób przechowujesz swoje dane. Czy przechowujesz zestawy tablic z X, Y, Z, W, czy przechowujesz wiele X, dużo Y, dużo Z i dużo W w osobnych tablicach [zakładając, że robimy obliczenia 3D]? W zależności od sposobu obliczania może się okazać, że wykonanie jednej lub drugiej strony da najlepsze korzyści.
Zrobiłem sporo SSE i 3DNow! optymalizacje kilka lat temu, a "sztuczka" często jest bardziej związana z przechowywaniem danych, dzięki czemu można łatwo pobrać "pakiet" odpowiedniego rodzaju danych za jednym razem. Jeśli dane są przechowywane w niewłaściwy sposób, tracisz dużo czasu na "przeskakiwanie danych" (przenoszenie danych z jednego sposobu przechowywania na inny).
Brak wzmianki o platformie? Niektóre platformy odmówią uruchomienia kodu za pomocą avx, nawet jeśli wiesz, że te instrukcje nigdy nie będą wywoływane. Niektóre platformy mają ifunc do wyboru między kilkoma implementacjami w czasie wykonywania. Niektóre platformy szukają bibliotek współdzielonych w ścieżkach zależnych od możliwości. –