CUDA纹理绑定
size_t fea_pitch;
texture<unsigned char, 2> features2D;
cudaMallocPitch((void**)(&dev_features), &fea_pitch, sizeof(unsigned char) * sfeaturesw, sfeaturesh);
cudaChannelFormatDesc feaDesc = cudaCreateChannelDesc<unsigned char>();
cudaMemcpy2D(dev_features, fea_pitch, sfeatures, sizeof(unsigned char) * sfeaturesw, sizeof(unsigned char) * sfeaturesw, sfeaturesh, cudaMemcpyHostToDevice);
cudaBindTexture2D(NULL, features2D, dev_features, feaDesc, sfeaturesw, sfeaturesh, fea_pitch);//绑定
纹理拾取(读取)的步骤
point1=tex2D(imageData2D,box_x+x1,box_y+y1);//第y1行,第x1列,cpu版即这个意思,此处尤须注意,和一般数据结构不同
另外纹理features2D不能直接修改,修改的话必须修改features2D所指的内存,即修改dev_features
3][3]={1,2,3,
4,5,6,
7,8,9};
tex2D( rT, x, y );取的是rT所绑定的二维数组T的T[y][x],即T的第y行第x列
cudaMallocPitch((void**)(&dev_features), &fea_pitch, sizeof(unsigned char) * sfeaturesw, sfeaturesh);
cudaChannelFormatDesc feaDesc = cudaCreateChannelDesc<unsigned char>();
cudaMemcpy2D(dev_features, fea_pitch, sfeatures, sizeof(unsigned char) * sfeaturesw, sizeof(unsigned char) * sfeaturesw, sfeaturesh, cudaMemcpyHostToDevice);
cudaBindTexture2D(NULL, features2D, dev_features, feaDesc, sfeaturesw, sfeaturesh, fea_pitch); --------------------------------------------------------------------------------
int sfeatures_size = sizeof(unsigned char) * sfeaturesw * sfeaturesh;
cudaChannelFormatDesc chDesc2 = cudaCreateChannelDesc<unsigned char>();
cudaMallocArray(&featuresArray, &chDesc2, sfeaturesw, sfeaturesh);
cudaMemcpyToArray( featuresArray, 0, 0, sfeatures, sfeatures_size, cudaMemcpyHostToDevice );
cudaBindTextureToArray( features2D, featuresArray);
-------------------------------------------------------------------------------------
int grid_data_size = sizeof(float) * gridl;
cudaMalloc((void**)&dev_grid,grid_data_size);
cudaMemcpy(dev_grid,sgrid,grid_data_size,cudaMemcpyHostToDevice);
cudaBindTexture(0,gridData1D,dev_grid);
对于一维纹理,不管是Linear Memory还是使用cudaMallocPitch的,都可以使用tex1Dfetch和tex1D
而对于二维纹理,不管是cudaArray还是cudaMallocPitch都是使用tex2D
下面是关于cudaMemcpy2D和cudaMallocPitch两个函数的参数和用法
最近学习了下CUDA矩阵内存对齐分配的方法,主要是cudaMemcpy2D和cudaMallocPitch两个函数的用法,先看看cudalibrary中如何定义的这两个函数:
cudaError_t cudaMallocPitch | ( | void ** | devPtr, | |
size_t * | pitch, | |||
size_t | width, | |||
size_t | height | |||
) |
Allocates at least widthInBytes
* height
bytes of linear memory on the device and returns in *devPtr
a pointer to the allocated memory. The function may pad the allocation to ensure that corresponding pointers in any given row will continue to meet the alignment requirements for coalescing as the address is updated from row to row. The pitch returned in *pitch
by cudaMallocPitch() is the width in bytes of the allocation. The intended usage of pitch
is as a separate parameter of the allocation, used to compute addresses within the 2D array. Given the row and column of an array element of type T
, the address is computed as:
T* pElement = (T*)((char*)BaseAddress + Row * pitch) + Column;
For allocations of 2D arrays, it is recommended that programmers consider performing pitch allocations using cudaMallocPitch(). Due to pitch alignment restrictions in the hardware, this is especially true if the application will be performing 2D memory copies between different regions of device memory (whether linear memory or CUDA arrays).
- Parameters:
-
devPtr - Pointer to allocated pitched device memory pitch - Pitch for allocation width - Requested pitched allocation width height - Requested pitched allocation height
cudaError_t cudaMemcpy2D | ( | void * | dst, | |
size_t | dpitch, | |||
const void * | src, | |||
size_t | spitch, | |||
size_t | width, | |||
size_t | height, | |||
enum cudaMemcpyKind | kind | |||
) |
Copies a matrix (height
rows of width
bytes each) from the memory area pointed to by src
to the memory area pointed to by dst
, where kind
is one ofcudaMemcpyHostToHost, cudaMemcpyHostToDevice, cudaMemcpyDeviceToHost, or cudaMemcpyDeviceToDevice, and specifies the direction of the copy. dpitch
and spitch
are the widths in memory in bytes of the 2D arrays pointed to by dst
and src
, including any padding added to the end of each row. The memory areas may not overlap. Calling cudaMemcpy2D() with dst
and src
pointers that do not match the direction of the copy results in an undefined behavior. cudaMemcpy2D() returns an error if dpitch
or spitch
is greater than the maximum allowed.
- Parameters:
-
dst - Destination memory address dpitch - Pitch of destination memory src - Source memory address spitch - Pitch of source memory width - Width of matrix transfer (columns in bytes) height - Height of matrix transfer (rows) kind - Type of transfer
由此,可以对这两个函数有个充分的认识。此外,cudaMallocPitch和cudaMemcpy2D,一般用于二维数组各维度size不是2的幂次方的问题。使用cudaMallocPitch()那么该数组的对齐、大小、起始址等就自动做好了,其返回的pitch就是真正分配给数组的size(往往大于其真正申请的大小)。
PS:
patch的理解:
C语言申请2维内存时,一般是连续存放的。a[y][x]存放在第y*widthofx*sizeof(元素)+x*sizeof(元素)个字节。但在cuda的global memory访问中,从256字节对齐的地址(addr=0, 256, 512, ...)开始的连续访问是最有效率的。 这样,为了提高内存访问的效率,有了cudaMallocPitch函数。 cudaMallocPitch函数分配的内存中,数组的每一行的第一个元素的开始地址都保证是对齐的。因为每行有多少个数据是不确定的widthofx*sizeof(元素)不一定是256的倍数。故此,为保证数组的每一行的第一个元素的开始地址对齐,cudaMallocPitch在分配内存时,每行会多分配一些字节,以保证widthofx*sizeof(元素)+多分配的字节是256的倍数(对齐)。这样,y*widthofx*sizeof(元素)+x*sizeof(元素)来计算a[y][x]的地址就不正确了。而应该是y*[widthofx*sizeof(元素)+多分配的字节]+x*sizeof(元素)。而函数中返回的pitch的值就是widthofx*sizeof(元素)+多分配的字节。
一、内存对齐的原因
大部分的参考资料都是如是说的:
1、平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据 的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。
2、性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐。 原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。
CUDA纹理绑定的更多相关文章
- cuda纹理内存的使用
CUDA纹理内存的访问速度比全局内存要快,因此处理图像数据时,使用纹理内存是一个提升性能的好方法. 贴一段自己写的简单的实现两幅图像加权和的代码,使用纹理内存实现. 输入:两幅图 lena, moon ...
- CUDA 纹理内存
原文链接 1.概述 纹理存储器中的数据以一维.二维或者三维数组的形式存储在显存中,可以通过缓存加速访问,并且可以声明大小比常数存储器要大的多. 在kernel中访问纹理存储器的操作称为纹理拾取(tex ...
- CUDA 纹理的使用
纹理绑定有两种,一个是绑定到线性内存就是用cudaMalloc();cudaMemcpy();开辟的内存空间,另一种是绑定到cudaMallocArray, cudaMemcpyToArray开辟到的 ...
- CUDA Texture纹理存储器 示例程序
原文链接 /* * Copyright 徐洪志(西北农林科技大学.信息工程学院). All rights reserved. * Data: 2012-4-20 */ // // 此程序是演示了1D和 ...
- CUDA中多维数组以及多维纹理内存的使用
纹理存储器(texture memory)是一种只读存储器,由GPU用于纹理渲染的图形专用单元发展而来,因此也提供了一些特殊功能.纹理存储器中的数据位于显存,但可以通过纹理缓存加速读取.在纹理存储器中 ...
- CUDA:纹理内存
纹理内存: 与常量内存类似,纹理内存是另一种形式的只读内存,并且同样缓存在芯片上.因此某些情况下能够减少对内存的请求并提供高效的内存带宽.纹理内存是专门为那些在内存访问模式中存在大量空间局部性的图形应 ...
- CUDA一维纹理内存
纹理一词来源于GPU图形世界,GPU通用并行计算"盗用"了纹理一词,定义了一个纹理内存的概念.纹理内存缓存在 设备上,在某些情况下能减少对内存的请求并降低内存带宽的使用,是专门为那 ...
- CUDA编程
目录: 1.什么是CUDA 2.为什么要用到CUDA 3.CUDA环境搭建 4.第一个CUDA程序 5. CUDA编程 5.1. 基本概念 5.2. 线程层次结构 5.3. 存储器层次结构 5.4. ...
- CUDA并行存储模型
CUDA将CPU作为主机(Host),GPU作为设备(Device).一个系统中可以有一个主机和多个设备.CPU负责逻辑性强的事务处理和串行计算,GPU专注于执行高度线程化的并行处理任务.它们拥有相互 ...
随机推荐
- 马踏棋盘问题-贪心(MATLAB&C++)
原创文章,转载请注明:马踏棋盘问题-贪心(MATLAB&C++) By Lucio.Yang 1.问题描述 将马随机放在国际象棋的Board[0-7][0-7]的某个方格中,马按走棋规则进行移 ...
- Linq 入门 顺带 Func与Action
Linq的优点: 查询是一种从数据源检索数据的表达式. 查询通常用专门的查询语言来表示. 随着时间的推移,人们已经为各种数据源开发了不同的语言:例如,用于关系数据库的 SQL 和用于 XML 的 XQ ...
- C# DES加解密
加密 public static string Encrypt(string sourceString, string key, string iv) { try { byte[] btKey = E ...
- System.Reflection.Emit学习
C#反射发出System.Reflection.Emit学习 分享: 1 一.System.Reflection.Emit概述 Emit,可以称为发出或者产生.与Emit相关的类基本都存在于Syste ...
- LintCode-三数之和 II
题目描述: 给一个包含n个整数的数组S, 找到和与给定整数target最接近的三元组,返回这三个数的和. 注意事项 只需要返回三元组之和,无需返回三元组本身 样例 例如S = . 和最接近1的三元组 ...
- 64位linux下安装oracle10 64位 遇到 :ins_ctx.mk ;ins_emdb.mk
http://blog.csdn.net/bamuta/article/details/10523835 http://www.cnblogs.com/kerrycode/p/3519446.html ...
- 以程序的方式操纵NTFS的文件权限(陈皓)
http://blog.csdn.net/haoel/article/details/2905 http://blog.sina.com.cn/s/blog_7f91494101018nmn.html
- (C#)Windows Shell 外壳编程系列6 - 执行
原文(C#)Windows Shell 外壳编程系列6 - 执行 (本系列文章由柠檬的(lc_mtt)原创,转载请注明出处,谢谢-) 接上一节:(C#)Windows Shell 外壳编程系列5 - ...
- Python中type与Object的区别
Python中type与Object的区别 在查看了Python的API后,总算明白了.现在总结如下: 先来看object的说明: Python中关于object的说明很少,甚至只有一句话: clas ...
- hdoj 3478 Catch(二分图判定+并查集)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3478 思路分析:该问题需要求是否存在某一个时刻,thief可能存在图中没一个点:将该问题转换为图论问题 ...