【问题标题】:How to use polymorphism in CUDA如何在 CUDA 中使用多态性
【发布时间】:2013-07-23 21:28:05
【问题描述】:

我正在将一些物理模拟代码从 C++ 移植到 CUDA。

基本算法可以理解为:对向量的每个元素应用一个算子。在伪代码中,模拟可能包括以下内核调用:

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

例如:

apply(add_three_operator, some_vector)

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

在我的 C++ 代码中,我有一个抽象基类 Operator,具有许多不同的具体实现。重要的方法是 类运算符{ 虚拟双操作(双 x)=0; 运算符 compose(运算符 lo,运算符 ro); ... }

AddOperator 的实现可能如下所示:

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

运算符类具有缩放和组合运算符具体实现的方法。这种抽象让我可以简单地将“叶”运算符组合成更一般的转换。

例如:

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

将添加三个然后平方向量的每个元素。

问题是 CUDA 不支持内核中的虚拟方法调用。我目前的想法是使用模板。然后内核调用看起来像:

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

有什么建议吗?

【问题讨论】:

  • 我相信virtual 函数需要使用-arch=sm_20 或更高版本进行编译。但是,我建议将您的多态性与启动内核的主机代码隔离开来。即使你最终编译了东西,我预计 SIMD 代码中虚拟函数调度的性能也会令人失望。
  • 我同意杰瑞德的观点。即使在 CPU 上,如果对大向量的每个元素都应用相同的操作,我会考虑重构,使多态性处于更高级别,并且虚拟方法调用不在您的内部循环中。一旦你这样做了,并行化将更加高效(在 CUDA、OpenMP 或其他中)。您也可以考虑使用 Thrust。
  • 感谢您的反馈。我实际上已经在使用 Thrust。我将继续使用模板。
  • 那么有没有我们可以真正回答的问题?

标签: cuda polymorphism


【解决方案1】:

可能是这样的……

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){...}

【讨论】:

    猜你喜欢
    • 2015-07-22
    • 2016-10-31
    • 2013-04-10
    • 1970-01-01
    • 1970-01-01
    • 2023-03-29
    • 2012-03-06
    • 2015-01-20
    • 1970-01-01
    相关资源
    最近更新 更多