CUDA编程——纹理内存

来源:互联网 发布:交换机修改telnet端口 编辑:程序博客网 时间:2024/05/22 03:08

IT168 文档

       (一)纹理属性

  (二)纹理拾取函数

  (三)拾取纹理内存与读取全局或常量内存相比的优点

  (一)纹理属性

  纹理可以在线性内存或是CUDA数组(纹理内存)的任何区域。所以纹理拾取也就对存在与线性内存或CUDA数组中的纹理读取数据。

  共用运行组件(既可以运行在host又可以运行在设备)中给出了纹理类型texture。纹理拾取的第一个参数就是纹理参考,纹理参考定义要拾取哪部分纹理内存,它必须通过宿主运行时(只运行在宿主上)函数绑定到一些内存区域(称为纹理(texture)),然后才能供内核使用。下面就来看看纹理参考的不可变属性和可变属性。

  不可变属性

  纹理参考的声明是texture texRef;Type、Dim和ReadMode都是不可变属性。其中:

  Type指定拾取纹理时返回的数据类型;Type限制为基本的整数和浮点数类型,以及1-、

  2-和4-分量的向量类型之一。

  Dim指定纹理参考的维度,等于1、2或3;Dim是可选参数,缺省值为1;

  ReadMode等于cudaReadModeNormalizedFloat或

  cudaReadModeElementType。如果;ReadMode为cudaReadModeNormalizedFloat,且Type为16-位或8-位整数类型,则其值实际返回值为浮点数类型,即根据原整数类型的全范围进行归一化处理,结果被映射到 [0.0, 1.0]区间(对于无符号整数)或[-1.0, 1.0]为区间(对于有符号整数);例如,值0xff的无符号8-位纹理元素返回值为1;如果ReadMode为cudaReadModeElementType,则不执行任何转换;ReadMode是可选参数,默认为cudaReadModeElementType.

  可变属性

  纹理参考的可变属性包括寻址模式、纹理过滤和纹理坐标是否归一化。这些属性都是执行宿主运行时改变的,如cudaBindTextureToArray()执行时在硬件纹理单元(texture units)时。其中:

  addressMode,即如何处理超出范围的纹理坐标。寻址模式是大小为2的数组,数组的第一个和第二个元素分别指定第一个第二个纹理坐标的寻址模式:当寻址模式等于cudaAddressModeClamp时,超出范围的纹理坐标将使用clamp寻址:非归一化纹理坐标的情况下,小于0的值设置为0,大于等于N的值设置为N-1;归一化纹理坐标的情况下,小于0.0或大于1.0的值设置到区间[0.0,1.0)中。当寻址模式是cudaAddressModeWarp时,超出范围的纹理坐标使用warp模式:warp寻址仅使用纹理坐标的小数部分:如1.25当作0.25处理,-1.25当作0.75处理。默认情况下是cudaAddressModeClamp。cudaAddressModeWarp只支持归一化的纹理坐标。

  filterMode,过滤模式即当拾取纹理时,如何基于输入纹理坐标来计算返回的值。filterMode等于cudaFilterModePoint或cudaFilterModeLinear;如果它为cudaFilterModePoint,则返回值是纹理坐标最接近输入纹理坐标的纹理元素;如果它为cudaFilterModeLinear,则返回值是纹理坐标最接近输入纹理坐标的2个(对于1D纹理)、4个(对于1个2D纹理)或8给(对于3D纹理)的纹理元素的线性插值。cudaFilterModeLinear只对返回值是浮点类型有效。

  normalize,指定纹理坐标是否是归一化的;如果其值非0,则纹理中的所有元素都使用区间[0,1],而非区间[0,width-1]、[0,height-1]或[0,depth-1]中的纹理坐标来寻址,其中width、height和depth是纹理大小。

  在线性内存中分配的纹理:

  • 维度只能等于1;
  • 不支持纹理过滤;
  • 只能使用非归一化的整数纹理坐标寻址;
  • 寻址模式单一:越界的纹理访问将返回0值。

 

  (二)纹理拾取函数

  纹理拾取函数是设备运行时函数。纹理存储的区间不同,拾取的方式也不同。

  从线性内存中拾取,使用的函数是tex1Dfetch()的函数簇。如:

template<class Type>

Type tex1Dfetch(

texture
<Type, 1, cudaReadModeElementType> texRef, int x); 

float tex1Dfetch(

texture
<unsigned char1, cudaReadModeNormalizedFloat> texRef,

int x);

  这些函数用纹理坐标x拾取绑定到纹理参考texRef 的线性内存的区域。不支持纹理过滤和寻址模式。对于整数型,这些函数将会将整数型转化为单精度浮点型。除了这些函数,还支持2-和4-分量向量的拾取。如:

float4 tex1Dfetch(

texture
<uchar4, 1, cudaReadModeNormalizedFloat> texRef,

int x);

  用纹理坐标x拾取绑定到纹理参考的线性内存的区域。

  从CUDA数组中拾取,是用函数tex1D(),tex2D(),tex3D():

template<class Type, enum cudaTextureReadMode readMode>

Type tex1D(texture
<Type, 1, readMode> texRef,float x); 

template
<class Type, enum cudaTextureReadMode readMode>

Type tex2D(texture
<Type, 2, readMode> texRef,float x, float y); 

template
<class Type, enum cudaTextureReadMode readMode>

Type tex3D(texture
<Type, 3, readMode> texRef,float x, float y, float z);

  这些函数用用纹理坐标x,y,z拾取绑定到纹理参考 texRef 的CUDA数组。纹理参考的可变和不可变属性决定了如何理解坐标,在纹理拾取和返回值将做怎样的处理。

  (三)拾取纹理内存与读取全局或常量内存相比的优点

  1. 有高速缓存,如果CUDA数组中的纹理在片上的高速缓存中,则可以潜在的获得较高带宽

  2. 不受访问模式的约束。全局或常量内存读取必须遵循相应访存模式才能获得好的性能。如全局内存在单个指令中将32-位、64-位或128-位从全局内存读取到寄存器,单个指令读取的位数要尽量多;另外每个半warp中同时访问全局内存地址的每个线程应该进行排列,以便内存访问可以合并到单个邻近的、对齐的内存访问中。

  3. 寻址计算的延迟隐藏的更好,有时候会改善应用程序执行随机访问数据的性能。

  4. 打包的数据可以在单个操作中广播到多个独立变量中

  5. 8-位和16-位整数输入数据可以有选择地转化为[0.0,1.0]或[-1.0,1.0]区间内的32位浮点值

  6. 如果访问的是CUDA数组还有其他的功能,过滤、归一化纹理坐标、寻址模式

原创粉丝点击