CUDA

2013-07-23 38 views
6

'da polimorfizm nasıl kullanılır Bazı fizik simülasyon kodlarını C++ 'dan CUDA'ya aktarıyorum. Temel algoritma şu şekilde anlaşılabilir: bir vektörün her elemanına bir operatörün uygulanması. ÖrneğinCUDA

apply(Operator o, Vector v){ 
    ... 
} 

:

apply(add_three_operator, some_vector) 

vektörü her elemana üç eklersiniz pseudocode, bir simülasyon aşağıdaki çekirdek çağrıyı içerebilir.

C++ kodumda, çok farklı somut uygulamalara sahip soyut bir temel sınıf Operatörüm var. Önemli yöntem sınıfı Operatördür { sanal çift işlem (çift x) = 0; Operatör oluşturma (Operatör lo, Operatör ro); ... }

AddOperator için uygulama aşağıdaki gibi görünebilir:

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

operatör sınıfı ölçekleme ve Operatörü somut uygulamaları oluştururken için yöntemler vardır. Bu soyutlama, “yaprak” operatörlerini daha genel dönüşümlere sokmamı sağlıyor. Örneğin

:

apply(compose(add_three_operator, square_operator), some_vector); 

üç daha sonra vektör, her eleman kare eklenmektedir.

Sorun şu ki, CUDA çekirdekte sanal yöntem çağrılarını desteklemiyor. Şu anki düşüncem şablon kullanmaktır. Daha sonra çekirdek aramaları şu gibi bir şeye benzeyecektir:

apply<Composition<AddOperator,SquareOperator>> 
    (compose(add_three_operator, square_operator), some_vector); 

Herhangi bir öneriniz var mı? İnanıyorum belki böyle

+6

'virtual' fonksiyonlar' -ARCH = sm_20' veya üstü olan derleme gerektirir. Bununla birlikte, polimorfizminizi çekirdeği başlatan ana bilgisayar koduna ayırmanızı öneririm. Sonunda bir şeyler derlediyseniz bile, SIMD kodunda sanal işlev gönderiminin performansının hayal kırıklığına uğrayacağını tahmin ediyorum. –

+5

Jared ile aynı fikirdeyim. CPU üzerinde bile, eğer aynı işlemler büyük vektörlerin her elemanına uygulanırsa, polimorfizmin daha yüksek bir seviyede olmasını ve sanal yöntem çağrılarının iç döngülerde bulunmamasını sağlamak için tekrar gözden geçirmeyi düşünürdüm. Bunu yaptıktan sonra, paralelleştirme çok daha fazla olacaktır (CUDA, OpenMP veya herhangi bir şekilde). Bunun için Thrust'u da düşünebilirsiniz. – harrism

+0

Geri bildirim için teşekkürler. Ben zaten Thrust'ı kullanıyorum. Şablonlarla devam ediyorum. – user2611717

cevap

1

şey ...

template <class Op1, class Op2> 
class Composition {...} 

template <class Op1, class Op2> 
Composition<Op1, Op2> compose(Op1& op1, Op2& op2) {...} 

template<class C> 
void apply(C& c, VecType& vec){...}