CUDA的纹理内存讲解,来自翻译和补充官方文档 CUDA programming Guide

Texture and Surface Memory 

CUDA支持供GPU处理图形用的纹理硬件和表面(surface)内存,但是只支持一部分功能。从纹理和表面内存中读取数据可以得到很多好处(以后再说)。

有两个不同的API可以来获取纹理内存和表面内存:1.纹理参考API,支持所有设备。2.纹理对象API只支持计算能力在3.x的设备。纹理参考API有一定的限制,但是纹理对象API则没有。

纹理内存:纹理内存从设备函数(GPU运行的kernal)中读取,读取的方式叫做fetch。每一个fetch明确了一个叫纹理对象的参数或者一个叫纹理参考的参数(分别来自不同的API)。

纹理对象和纹理参考(reference)指定了:

  1. 哪块区域的纹理被fetch,纹理对象在运行时被创建,创建对象以后就被指定(即该对象绑定了这个纹理)。  纹理参考是在编译的时候创建的,在运行时通过绑定纹理参考到纹理而指定(即该纹理参考绑定了该对象)。不同的纹理参考可能会绑定绑定相同的纹理内存(或者绑定的纹理内存之间有重叠)。
  2. 纹理的维度会在指定纹理的时候明确,一维的纹理定义为一维数组,使用一维的坐标,二维的纹理定义为二维数组,使用二维坐标,以此类推。数组中每个元素叫纹素(texel),即纹理元素。纹理的长宽高代表了纹理在各个维度的大小。各个维度的最大值取决于GPU的计算能力。
  3. 纹理元素的类型被限制到基本整形和单精度浮点类型和任何包含1、2或4个元素的向量的类型(这些类型是从基本整形和单精度浮点类型扩展开的,定义为char,short,int long,longlong,float,double)。在CUDA里面,可以通过内置函数make_<类型名>来返回相应的向量,比如 int2  make_int2(int x,int y),就是返回一个int型向量,里面有两个元素。
  4. 读纹理的模式有两种,cudaReadModeNormalizedFloat 和cudaReadModeElementType ,如果是cudaReadModeNormalizedFloat ,纹理数据是16位或者8位的整形,读出的数是返回的浮点型,有符号整形变化范围-1.0到1.0,无符号读出来的是0到1.0。例如8位的纹理元素值为0xff,读出来以后值为1,如果是cudaReadModeElementType,则不会发生转换。
  5. 无论纹理坐标是否单位化,缺省条件下(默认)纹理引用使用浮点坐标,范围[0,N-1],N是纹理在相应维度的大小(因为可以进行采样到两个纹理坐标的中间值,所以变化范围是浮点型的)。例如,纹理大小为64*32,则引用的坐标就是x和y维在[0,63]和[0,31]上的值,单位化的纹理坐标就是纹理索引在[0.0,1.0-1/N]而不是[0,N-1],所以64*32的数据纹理的横纵坐标索引都可以用[0.0,1-1/N]来进行索引。
  6. 寻址方式,fetch的时候越界是合法的,默认会把非单位化的坐标进行压缩到[0,N),单位化的压缩到[0,1.0),就是说如果在边界外采样,则归到边界点上。如果设定边界(border)模式,则越界的会返回0,对于单位化的坐标,有warp mode和mirror mode,warp mode时,假设如果采样点为x(如1.1),则采样值为x*floor(x),这里的floor(x)是比x小的最大的整数值,这里为1。Mirror模式中,floor(x)为偶数,则采样值为x*floor(x),如果为奇数,则采样值为1-x*floor(x)。
  7. 滤波器模式指定了值怎么被滤波的,如果是线性滤波器,则仅对纹理配置返回浮点型数据,执行邻域低精度插值,比如三线性滤波器对三维纹理插值,

cudaFilterModePoint 返回离着采样纹理坐标最近的那个坐标的值,cudaFilterModeLinear 则返回线性插值的坐标,只支持返回值的浮点类型。

 

Logo

欢迎来到由智源人工智能研究院发起的Triton中文社区,这里是一个汇聚了AI开发者、数据科学家、机器学习爱好者以及业界专家的活力平台。我们致力于成为业内领先的Triton技术交流与应用分享的殿堂,为推动人工智能技术的普及与深化应用贡献力量。

更多推荐