GPUMetal上的C ++类型,如何将另一个变量的类型保存到一个类中,并确保所有类实例具有相同的大小?

问题描述

cpu端的伪代码

class Sphere {
//some property 
}

class Square {
//some property
}

class BVH {
    Type type; // save the type of Sphere or Square,or other types.
    // But the instance of this class should maintain the same size.
}

可以使用enum作为类型,然后检查类型并在GPU上分支。我已经在GPU上工作了。但是,如果我可以将type直接保存到此类中,也许我可以进行类型转换并在GPU上使用模板。以我的理解,它将减少所有难看的分支。

所有逻辑都发生在GPU端,cpu端仅在准备数据。 GPU(金属)不具有超类和虚拟功能,但支持模板。最好避免使用任何std东西,除非我可以在GPU上获得相同的类型。

解决方法

自从您谈到解析到GPU以来,我假设您需要的是一个丑陋的解决方案,并且您将重点放在它的高效而不是可读性和美观性上。这看起来像这样:

union Figure
{
    Square square;
    Sphere sphere;
};

class BVH {

public:

    enum class FigureType { Square,Sphere };
    BVH(Square square) // or const Square& square,or move...
    {
        type = FigureType::Square;
        figure.square = square;
    }
    BVH(Sphere sphere) { ... }
    // Or instead of the two signatures above,// BVH(Figure figure,FigureType type);
    // although that would allow the two parameters to not match.
    // One might even consider to make the enum private.

    void process()
    {
        // or switch
        if(type == FigureType::Square) process_square();
        ...
    }

private:

    FigureType type;
    Figure figure;

    void process_square()
    {
        figure.square.do_something();
    }
}

有关union的更多信息,请参见https://en.cppreference.com/w/cpp/language/union

但是,union仍然很丑陋,而我只在确实需要这样做时才提到这种可能性,丑陋的非常低级的编程。如果您可以通过制作BVH为模板,或者可以引入某个超类Figure,那么SquareSphere将从其中继承并让BVH存储一个指向Figure的指针,甚至在Figure为子类提供覆盖接口的情况下,也将是更好的选择。