В C++ я часто использую статические функции, инкапсулированные в шаблонные структуры, чтобы иметь возможность указывать шаблон функции во время компиляции, позволяя различные оптимизации, например, встраивание и т.д. (Кстати, имеет ли это имя?). Пример (довольно надуманный, и, вероятно, есть ошибки, но вы понимаете):
template <int dim>
struct ImplementationA {
static float compute(float a) {
// do stuff, e.g.
return 2*pow(a,dim);
}
};
template <int dim>
struct ImplementationB {
static float compute(float a) {
// do other stuff, e.g.
return 3*pow(a,dim);
}
};
template <template <int> class ImplT, int dim> class Test {
void compute_stuff(float *dst, const float *src, int N) {
for(int i=0; i<N; i++)
dst[i] = ImlT<dim>::compute(src[i]);
}
};
void main() {
float v1[100];
float v2[100];
Test<ImplementationB,3> t;
t.compute_stuff(v2,v1,N);
}
Однако, если я хочу сделать то же самое в CUDA с compute
являющимся ядром, то есть __global__
, это невозможно, поскольку у вас не может быть static __global__
функции static __global__
member. Какие у меня есть другие возможности, которые обеспечивают минимальные эксплуатационные издержки? Я использую GCC 4.6, поэтому некоторые функции C++ 11 недоступны.
Вы можете создать класс шаблона с реализацией в методе __device__
и малую функцию __global__
которая просто использует этот класс и вызывает метод:
template <int dim> class ImplementationA
{
public:
// parameters
float *dst;
const float *src;
int N;
// implementation
__device__ void compute()
{
float a = src[threadIdx.x];
// ...
}
};
// The same for ImplementationB
// global function
template <class Impl>
__global__ void compute(Impl impl)
{
impl.compute();
}
// call
ImplementationA<3> impl;
impl.src = src;
compute<<<1, 32>>>(impl);
jet45
бы также.