考虑到模板参数,正在更改if语句条件

Altering if-statement condition in consideration of template argument

本文关键字:if 语句 条件 参数 考虑到      更新时间:2023-10-16

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

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])

直接的方法是暴力:

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

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

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

template<int ARG>
class IfCondition {
};

并针对CCD_ 12:的不同值进行专门化

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

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

ARG==1if语句看起来像:if(expr2({body}

ARG==2if语句看起来像:if(expr1&&expr2({body}

直接编码,因为这是您自己对可读的解释。

由于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}