Reputation: 1507
I have a global kernel function with template argument:
template<int ARG> __global__ void kernel(array[]) {
int threadID = blockDim.x*blockIdx.x + threadIdx.x;
if(...) {...}
}
The behaviour of the function, and a specially if-statement condition, is slightly varying in consideration of template argument but the body stays the same. Lets say:
ARG == 0
if statement looks like: if(expr1){body}
ARG == 1
if statement looks like: if(expr2){body}
ARG == 2
if statement looks like: if(expr1 && expr2){body}
My question is what is the best way(in a sense of readability and performance) to provide this?
EDIT:
Expressions expr1
and expr2
are calls to __device__ boolean
functions, e.g. fnc1(array[threadID])
and fnc2(array[threadID])
.
Upvotes: 1
Views: 425
Reputation: 63946
ARG == 0 if statement looks like: if(expr1){body}
ARG == 1 if statement looks like: if(expr2){body}
ARG == 2 if statement looks like: if(expr1 && expr2){body}
Code that directly, since that's your own interpretation of readable.
It will be performant since ARG
can be resolved at compile time.
if ( ARG == 0 && expr1 ) {body}
if ( ARG == 1 && expr2) {body}
if ( ARG == 2 && expr1 && expr2 ) {body}
Or, if {body}
is heavy, combine them.
if ( ARG == 0 && expr1 ) ||
( ARG == 1 && expr2) ||
( ARG == 2 && expr1 && expr2 ) {body}
Upvotes: 0
Reputation: 2518
You can declare an auxiliary class template:
template<int ARG>
class IfCondition {
};
and specialize it for different values of 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;
}
};
Then use it inside your template like this:
if (IfCondition<ARG>::Get())
...
}
The nice thing about it is that, with inlining, it'll be as fast as literally writing if(expr1) {body}
or if (expr2) {body}
or whatnot.
EDIT
Another way to go is with template function specialization:
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>()) {
...
}
Upvotes: 1
Reputation: 76498
The straightforward approach is brute force:
if ((ARG != 1 || expr1) && (ARG != 0 || expr2)) ...
Since ARG is known at compile time, the compiler will generate good code here.
Upvotes: 6