Przesyłam kod symulacji fizyki z C++ do CUDA.Jak korzystać z polimorfizmu w CUDA
Podstawowy algorytm można rozumieć jako: zastosowanie operatora do każdego elementu wektora. W Pseudokod, symulacja może zawierać następujące połączenia jądra:
apply(Operator o, Vector v){
...
}
Na przykład:
apply(add_three_operator, some_vector)
by dodać trzy do każdego elementu w wektorze.
W moim kodzie C++ mam abstrakcyjnego operatora klasy podstawowej, z wieloma różnymi implementacjami konkretnymi. Ważną metodą jest operator klasy { wirtualna podwójna operacja (podwójne x) = 0; Komponent operatora (operator lo, operator ro); ... }
Implementacja AddOperator może wyglądać następująco:
class AddOperator : public Operator{
private:
double to_add;
public:
AddOperator(double to_add): to_add(to_add){}
double operator(double x){
return x + to_add;
}
};
Klasa operator ma metody skalowania i komponowania konkretne implementacje Operatora. Ta abstrakcja pozwala mi po prostu na komponowanie operatorów "liści" w bardziej ogólne przekształcenia.
na przykład:
apply(compose(add_three_operator, square_operator), some_vector);
doda trzy następnie kwadratowych każdy element wektora.
Problem polega na tym, że CUDA nie obsługuje wywołań metod wirtualnych w jądrze. Moja obecna myśl polega na używaniu szablonów. Następnie wywołania jądra będą wyglądały mniej więcej:
apply<Composition<AddOperator,SquareOperator>>
(compose(add_three_operator, square_operator), some_vector);
Jakieś sugestie?
wierzę 'funkcje virtual' wymagają kompilacji z' -arch = sm_20' lub wyższej. Jednak zaleciłbym izolowanie twojego polimorfizmu od kodu hosta, który uruchamia jądro. Nawet jeśli w końcu uzyskasz kompilację, spodziewam się, że wydajność wysyłania funkcji wirtualnych w kodzie SIMD będzie rozczarowująca. –
Zgadzam się z Jared. Nawet w CPU, jeśli te same operacje są stosowane do każdego elementu dużych wektorów, rozważałbym refaktoryzację, aby polimorfizm był na wyższym poziomie, a wywołania metod wirtualnych nie były w twoich wewnętrznych pętlach. Gdy to zrobisz, równoległość będzie znacznie bardziej wydajna (w CUDA, OpenMP lub cokolwiek innego). Możesz również rozważyć Thrust w tym zakresie. – harrism
Dzięki za opinię. Właściwie używam już narzędzia Thrust. Idę naprzód z szablonami. – user2611717