我用CUDA开发了以下插值,我正在寻找一种改进这种插值的方法。出于某些原因,我不想使用CUDA纹理。
另一点我注意到,由于某些未知的原因,如果向量的大小优于线程的数量(例如,使用向量的向量),则在我的情况下不对整个向量执行插值。大小为1000,并且线程数等于512,一个线程完成它的第一个工作就是全部。我想优化singleInterp函数。
这是我的代码:
__device__ float singleInterp(float* data, float x, int lx_data) {
float res = 0;
int i1=0;
int j=lx_data;
int imid;
while (j>i1+1)
{
imid = (int)(i1+j+1)/2;
if (data[imid]<x)
i1=imid;
else
j=imid;
}
if (i1==j)
res = data[i1+lx_data];
else
res =__fmaf_rn( __fdividef(data[j+lx_data]-data[i1+lx_data],(data[j]-data[i1])),x-data[i1], data[i1+lx_data]);
return res;
}
内核:
__global__ void linearInterpolation(float* data, float* x_in, int lx_data) {
int i = threadIdx.x + blockDim.x * blockIdx.x;
int index = i;
if (index < lx_data)
x_in[index] = singleInterp(data, x_in[index], lx_data);
}
答案 0 :(得分:1)
您似乎对1D线性插值感兴趣。我已经遇到了优化这种插值的问题,最后我得到了以下代码
__global__ void linear_interpolation_kernel_function_GPU(double* __restrict__ result_d, const double* __restrict__ data_d, const double* __restrict__ x_out_d, const int M, const int N)
{
int j = threadIdx.x + blockDim.x * blockIdx.x;
if(j<N)
{
double reg_x_out = x_out_d[j/2]+M/2;
int k = floor(reg_x_out);
double a = (reg_x_out)-floor(reg_x_out);
double dk = data_d[2*k+(j&1)];
double dkp1 = data_d[2*k+2+(j&1)];
result_d[j] = a * dkp1 + (-dk * a + dk);
}
}
假设数据在-M/2
和M/2
之间的整数节点处采样。
该代码与1D纹理插值“等效”,如下面的web-page所述。对于1D线性纹理插值,请参见CUDA-Programming-Guide的图13。有关不同解决方案之间的比较,请参阅以下thread。