1

我有一个带有模板参数的全局内核函数:

template<int ARG> __global__ void kernel(array[]) {
    int threadID = blockDim.x*blockIdx.x + threadIdx.x;
    if(...) {...}
}

考虑到模板参数,函数的行为以及特别的 if 语句条件略有不同,但主体保持不变。可以说:
ARG == 0if 语句看起来像:if(expr1){body}
ARG == 1if 语句看起来像:if(expr2){body}
ARG == 2if 语句看起来像:if(expr1 && expr2){body}

我的问题是提供此功能的最佳方式(在可读性和性能方面)是什么?

编辑: 表达式expr1expr2是对__device__ boolean函数的调用,例如fnc1(array[threadID])fnc2(array[threadID])

4

3 回答 3

6

直接的方法是蛮力:

if ((ARG != 1 || expr1) && (ARG != 0 || expr2)) ...

由于 ARG 在编译时是已知的,因此编译器会在这里生成好的代码。

于 2013-04-02T14:31:28.687 回答
1

您可以声明一个辅助类模板:

template<int ARG>
class IfCondition {
};

并将其专门用于不同的值ARG

template<>
class IfCondition<0> {
public:
    static bool Get() {
        return expr1;
    }
};

template<>
class IfCondition<1> {
public:
    static bool Get() {
        return expr2;
    }
};

template<>
class IfCondition<2> {
public:
    static bool Get() {
        return expr1 && expr2;
    }
};

然后在您的模板中使用它,如下所示:

if (IfCondition<ARG>::Get())
     ...

}

关于它的好处是,通过内联,它会像字面上的书写一样if(expr1) {body}if (expr2) {body}

编辑

另一种方法是使用模板函数专业化:

template<int ARG>
bool ifCondition() { return false; }

template<>
bool ifCondition<0>() { return expr1; }

template<>
bool ifCondition<1>() { return expr2; }

template<>
bool ifCondition<2>() { return expr1 && expr2; }

// Then later, inside your template:
if (ifCondition<ARG>()) {
    ...
}
于 2013-04-02T14:37:52.063 回答
0

ARG == 0 if 语句看起来像:if(expr1){body}

ARG == 1 if 语句如下所示: if(expr2){body}

ARG == 2 if 语句如下所示: if(expr1 && expr2){body}

直接编码,因为这是你自己对readable的解释。

它将是高性能的,因为ARG可以在编译时解决。

if ( ARG == 0 && expr1 ) {body}

if ( ARG == 1 && expr2) {body}

if ( ARG == 2 && expr1 && expr2 ) {body}

或者,如果{body}很重,将它们组合起来。

if ( ARG == 0 && expr1 ) ||

   ( ARG == 1 && expr2) ||

   ( ARG == 2 && expr1 && expr2 ) {body}
于 2013-04-02T14:49:55.333 回答