我尝试从纹理中读取值并将它们写回全局内存。 我确信写作部分有效,因为我可以在内核中放置常量值,我可以在输出中看到它们:
__global__ void
bartureKernel( float* g_odata, int width, int height)
{
unsigned int x = blockIdx.x*blockDim.x + threadIdx.x;
unsigned int y = blockIdx.y*blockDim.y + threadIdx.y;
if(x < width && y < height) {
unsigned int idx = (y*width + x);
g_odata[idx] = tex2D(texGrad, (float)x, (float)y).x;
}
}
我想要使用的纹理是具有两个通道的2D浮动纹理,因此我将其定义为:
texture<float2, 2, cudaReadModeElementType> texGrad;
调用内核的代码用一些常量非零值初始化纹理:
float* d_data_grad = NULL;
cudaMalloc((void**) &d_data_grad, gradientSize * sizeof(float));
CHECK_CUDA_ERROR;
texGrad.addressMode[0] = cudaAddressModeClamp;
texGrad.addressMode[1] = cudaAddressModeClamp;
texGrad.filterMode = cudaFilterModeLinear;
texGrad.normalized = false;
cudaMemset(d_data_grad, 50, gradientSize * sizeof(float));
CHECK_CUDA_ERROR;
cudaBindTexture(NULL, texGrad, d_data_grad, cudaCreateChannelDesc<float2>(), gradientSize * sizeof(float));
float* d_data_barture = NULL;
cudaMalloc((void**) &d_data_barture, outputSize * sizeof(float));
CHECK_CUDA_ERROR;
dim3 dimBlock(8, 8, 1);
dim3 dimGrid( ((width-1) / dimBlock.x)+1, ((height-1) / dimBlock.y)+1, 1);
bartureKernel<<< dimGrid, dimBlock, 0 >>>( d_data_barture, width, height);
我知道,将纹理字节设置为全“50”在浮点数的上下文中没有多大意义,但它至少应该给我一些非零值来读取。
我只能读零...
答案 0 :(得分:7)
您正在使用cudaBindTexture
将纹理绑定到cudaMalloc
分配的内存。在内核中,您使用tex2D
函数从纹理中读取值。这就是它读零的原因。
如果使用cudaBindTexture
将纹理绑定到线性内存,则使用内核中的tex1Dfetch
读取纹理。
tex2D
用于仅使用函数cudaMallocPitch
从那些绑定到音高线性内存(由cudaBindTexture2D
分配)的纹理中读取,或使用函数cudaBindTextureToArray
这是基本表,其余的可以从编程指南中读取:
内存类型 ----------------- 使用分配 ------------ ----- 使用绑定----------------------- 通过 <读取内核/ p>
线性记忆................... cudaMalloc
..................... ... cudaBindTexture
{............................. {1}}
音高线性记忆......... tex1Dfetch
............. cudaMallocPitch
............ ............ cudaBindTexture2D
cudaArray ............................ tex2D
............. cudaMallocArray
............. cudaBindTextureToArray
或tex1D
3D cudaArray ...................... tex2D
........ cudaMalloc3DArray
..... ........ cudaBindTextureToArray
答案 1 :(得分:2)
要添加,使用tex1Dfetch的访问基于整数索引。 但是,其余的都是基于浮点索引的,你必须添加+0.5才能得到你想要的确切值。
我很好奇你为什么要创建float并绑定到float2纹理?它可能会产生模棱两可的结果。 float2不是2D浮动纹理。它实际上可以用于表示复数。
typedef struct {float x; float y;} float2;
我认为本教程将帮助您了解如何在cuda中使用纹理内存。 http://www.drdobbs.com/parallel/cuda-supercomputing-for-the-masses-part/218100902
您显示的内核不会因使用纹理而受益匪浅。但是,如果利用得当,通过利用局部性,纹理记忆可以相当多地提高性能。此外,它对插值很有用。