纹理内存

纹理内存是针对图形应用的空间局部性优化的只读缓存。在CUDA中,纹理缓存提供快速访问,通过纹理拾取操作如tex1D(), tex2D(), tex3D()进行读取。纹理内存具有缓存重复利用和预取滤波功能。CUDA数组与纹理绑定,优化了纹理访问,仅能在设备端通过纹理拾取访问。示例展示了如何在CUDA程序中创建、绑定纹理数组并进行旋转操作。" 122823857,1443732,分布式系统:ACID、CAP与Base理论解析,"['分布式系统', '数据库理论', '事务管理', '分布式数据库']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

定义

纹理缓存是专门为那些在内存访问模式中存在大量空间局部性(Spatial Locality)的图形应用程序而设计。只读

在kernel中访问纹理存储器的操作称为纹理拾取(texture fetching)

将显存中的数据与纹理参照系关联的操作,称为将数据与纹理绑定(texture binding).

  显存中可以绑定到纹理的数据有两种,分别是普通的线性存储器和cuda数组。

  :线性存储器只能与一维或二维纹理绑定,采用整型纹理拾取坐标,坐标值与数据在存储器中的位置相同;

        CUDA数组可以与一维、二维、三维纹理绑定,纹理拾取坐标为归一化或者非归一化的浮点型,并且支持许多特殊功能。


纹理缓存

Texture mem的访问速度快于Global mem,是因为纹理内存有缓存,只有当缓存没有命中的时候才会去访问设备内存,否则访问纹理缓存具有很小​​的延迟。有如下特点:

(1)纹理缓存中的数据可以被重复利用

(2)纹理缓存一次预取拾取坐标对应位置附近的几个象元,可以实现滤波模式。


应用

这里主要讨论CUDA数组。对与一维、二维、三维cuda数组绑定的纹理,分别使用tex1D(), tex2D() 和 tex3D()函数访问,并且使用浮点型纹理坐标。

注意:CUDA数组为纹理访问进行了优化,并且在Device端只能通过纹理拾取访问。

实例如下:

texture<float, 2, cudaReadModeElementType> texRef;// 2D float texture

__global__ void transformKernel(float* output, int width, int height, float theta)

{

     

     unsigned int x = blockIdx.x * blockDim.x + threadIdx.x; // 根据tid bid计算归一化的拾取坐标

     unsigned int y = blockIdx.y * blockDim.y + threadIdx.y;

     float u = x / (float)width;

     float v = y / (float)height;

    

     u -= 0.5f;    // 旋转拾取坐标

     v -= 0.5f;

     float tu = u * cosf(theta) –v * sinf(theta) + 0.5f;

     float tv = v * cosf(theta) + u * sinf(theta) + 0.5f;

    

     output[y * width + x] = tex2D(tex, tu, tv);  //从纹理存储器中拾取数据,并写入显存

}

 

// Host code

int main()

{

     // 分配CUDA数组

cudaChannelFormatDesc channelDesc = cudaCreateChannelDesc(32, 0, 0,0,cudaChannelFormatKindFloat);

     cudaArray* cuArray;

     cudaMallocArray(&cuArray, &channelDesc, width, height);

     // Copy to device memory some data located at address h_data

     // in host memory

     cudaMemcpyToArray(cuArray, 0, 0, h_data, size, cudaMemcpyHostToDevice);


     // Set texture parameters

     texRef.addressMode[0] = cudaAddressModeWrap; //循环寻址方式

     texRef.addressMode[1] = cudaAddressModeWrap;

     texRef.filterMode = cudaFilterModeLinear; //因为这里是一个图像。若要保持原来的值则千万不要用线性滤波

     texRef.normalized = true; //归一化坐标

     

     cudaBindTextureToArray(texRef, cuArray, channelDesc);   // Bind the array to the texture

    

     float* output;    // Allocate result of transformation in device memory

     cudaMalloc((void**)&output, width * height * sizeof(float));

   

     dim3 dimBlock(16, 16);    // Invoke kernel

     dim3 dimGrid((width + dimBlock.x –1) / dimBlock.x,(height + dimBlock.y –1) / dimBlock.y);

     transformKernel<<<dimGrid, dimBlock>>>(output, width, height,angle);

   

     cudaFreeArray(cuArray);    // Free device memory

     cudaFree(output);

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

屠变恶龙之人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值