如何在CUDA中使用多态性

7
我将把一些物理模拟代码从C++移植到CUDA。
基本算法可以理解为:对向量的每个元素应用一个运算符。在伪代码中,模拟可能包括以下内核调用:
apply(Operator o, Vector v){
    ...
}

例如:
apply(add_three_operator, some_vector)

我将向向量中的每个元素添加三。

在我的C++代码中,我有一个抽象基类Operator,其中包含许多不同的具体实现。重要的方法是:

class Operator{ virtual double operate(double x) =0; Operator compose(Operator lo, Operator ro); ... }

加法运算符的实现可能如下所示:

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

操作类具有缩放和组合Operator的具体实现的方法。这种抽象允许我将“叶子”操作符简单地组合成更一般的转换。

例如:

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

我将新增三个元素,然后对向量中的每个元素进行平方处理。

问题在于CUDA不支持内核中的虚拟方法调用。我的当前思路是使用模板。这样,内核调用将类似于:

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

有什么建议吗?

6
我认为 virtual 函数需要使用 -arch=sm_20 或更高版本进行编译。但是,我建议将多态性隔离到启动内核的主机代码中。即使您最终使事情编译成功,我也预计在 SIMD 代码中虚函数分派的性能会令人失望。 - Jared Hoberock
5
我同意Jared的观点。即使在CPU上,如果对大向量的每个元素应用相同的操作,我也会考虑重构,使得多态性更高层次化,并且虚方法调用不在内循环中。一旦这样做,并行化将更加高效(在CUDA、OpenMP或其他平台上)。你还可以考虑使用Thrust来完成这个任务。 - harrism
感谢您的反馈。我已经在使用Thrust了。我将继续使用模板。 - user2611717
3
我们能真正回答的问题是什么? - harrism
1个回答

2

也许是这样的...

这里涉及到IT技术相关内容。
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){...}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接