cuda纹理内存的使用

CUDA纹理内存的访问速度比全局内存要快,因此处理图像数据时,使用纹理内存是一个提升性能的好方法。

贴一段自己写的简单的实现两幅图像加权和的代码,使用纹理内存实现。

输入:两幅图 lena, moon

  

输出:两幅图像加权和

 1 #include <opencv2\opencv.hpp>
 2 #include <iostream>
 3 #include <string>
 4 #include <cuda.h>
 5 #include <cuda_runtime.h>
 6 #include <device_launch_parameters.h>
 7
 8 using namespace std;
 9 using namespace cv;
10
11 //声明CUDA纹理
12 texture <uchar4, cudaTextureType2D, cudaReadModeNormalizedFloat> refTex1;
13 texture <uchar4, cudaTextureType2D, cudaReadModeNormalizedFloat> refTex2;
14 //声明CUDA数组
15 cudaArray* cuArray1;
16 cudaArray* cuArray2;
17 //通道数
18 cudaChannelFormatDesc cuDesc = cudaCreateChannelDesc<uchar4>();
19
20
21 __global__ void weightAddKerkel(uchar *pDstImgData, int imgHeight, int imgWidth,int channels)
22 {
23     const int tidx=blockDim.x*blockIdx.x+threadIdx.x;
24     const int tidy=blockDim.y*blockIdx.y+threadIdx.y;
25
26     if (tidx<imgWidth && tidy<imgHeight)
27     {
28         float4 lenaBGR,moonBGR;
29         //使用tex2D函数采样纹理
30         lenaBGR=tex2D(refTex1, tidx, tidy);
31         moonBGR=tex2D(refTex2, tidx, tidy);
32
33         int idx=(tidy*imgWidth+tidx)*channels;
34         float alpha=0.5;
35         pDstImgData[idx+0]=(alpha*lenaBGR.x+(1-alpha)*moonBGR.x)*255;
36         pDstImgData[idx+1]=(alpha*lenaBGR.y+(1-alpha)*moonBGR.y)*255;
37         pDstImgData[idx+2]=(alpha*lenaBGR.z+(1-alpha)*moonBGR.z)*255;
38         pDstImgData[idx+3]=0;
39     }
40 }
41
42 void main()
43 {
44     Mat Lena=imread("data/lena.jpg");
45     Mat moon=imread("data/moon.jpg");
46     cvtColor(Lena, Lena, CV_BGR2BGRA);
47     cvtColor(moon, moon, CV_BGR2BGRA);
48     int imgWidth=Lena.cols;
49     int imgHeight=Lena.rows;
50     int channels=Lena.channels();
51
52     //设置纹理属性
53     cudaError_t t;
54     refTex1.addressMode[0] = cudaAddressModeClamp;
55     refTex1.addressMode[1] = cudaAddressModeClamp;
56     refTex1.normalized = false;
57     refTex1.filterMode = cudaFilterModeLinear;
58     //绑定cuArray到纹理
59     cudaMallocArray(&cuArray1, &cuDesc, imgWidth, imgHeight);
60     t = cudaBindTextureToArray(refTex1, cuArray1);
61
62     refTex2.addressMode[0] = cudaAddressModeClamp;
63     refTex2.addressMode[1] = cudaAddressModeClamp;
64     refTex2.normalized = false;
65     refTex2.filterMode = cudaFilterModeLinear;
66      cudaMallocArray(&cuArray2, &cuDesc, imgWidth, imgHeight);
67     t = cudaBindTextureToArray(refTex2, cuArray2);
68
69     //拷贝数据到cudaArray
70     t=cudaMemcpyToArray(cuArray1, 0,0, Lena.data, imgWidth*imgHeight*sizeof(uchar)*channels, cudaMemcpyHostToDevice);
71     t=cudaMemcpyToArray(cuArray2, 0,0, moon.data, imgWidth*imgHeight*sizeof(uchar)*channels, cudaMemcpyHostToDevice);
72
73     //输出图像
74     Mat dstImg=Mat::zeros(imgHeight, imgWidth, CV_8UC4);
75     uchar *pDstImgData=NULL;
76     t=cudaMalloc(&pDstImgData, imgHeight*imgWidth*sizeof(uchar)*channels);
77
78     //核函数,实现两幅图像加权和
79     dim3 block(8,8);
80     dim3 grid( (imgWidth+block.x-1)/block.x, (imgHeight+block.y-1)/block.y );
81     weightAddKerkel<<<grid, block, 0>>>(pDstImgData, imgHeight, imgWidth, channels);
82     cudaThreadSynchronize();
83
84     //从GPU拷贝输出数据到CPU
85     t=cudaMemcpy(dstImg.data, pDstImgData, imgWidth*imgHeight*sizeof(uchar)*channels, cudaMemcpyDeviceToHost);
86
87     //显示
88     namedWindow("show");
89     imshow("show", dstImg);
90     waitKey(0);
91 }
时间: 2024-11-10 07:05:38

cuda纹理内存的使用的相关文章

CUDA 纹理内存

原文链接 1.概述 纹理存储器中的数据以一维.二维或者三维数组的形式存储在显存中,可以通过缓存加速访问,并且可以声明大小比常数存储器要大的多. 在kernel中访问纹理存储器的操作称为纹理拾取(texture fetching).将显存中的数据与纹理参照系关联的操作,称为将数据与纹理绑定(texture binding). 显存中可以绑定到纹理的数据有两种,分别是普通的线性存储器和cuda数组. 注:线性存储器只能与一维或二维纹理绑定,采用整型纹理拾取坐标,坐标值与数据在存储器中的位置相同:  

CUDA学习日志:常量内存和纹理内存

接触CUDA的时间并不长,最开始是在cuda-convnet的代码中接触CUDA代码,当时确实看的比较痛苦.最近得空,在图书馆借了本<GPU高性能编程 CUDA实战>来看看,同时也整理一些博客来加强学习效果. Jeremy Lin 在上一篇博文中,我们谈到了如何利用共享内存来实现线程协作的问题.本篇博文我们主要来谈谈如何利用常量内存和纹理内存来提高程序性能. 常量内存 所谓的常量内存,从它的名字我们就可以知道,它是用来保存在核函数执行期间不会发生变化的数据.NVIDIA硬件提供了64KB的常量

CUDA中多维数组以及多维纹理内存的使用

纹理存储器(texture memory)是一种只读存储器,由GPU用于纹理渲染的图形专用单元发展而来,因此也提供了一些特殊功能.纹理存储器中的数据位于显存,但可以通过纹理缓存加速读取.在纹理存储器中可以绑定的数据比在常量存储器可以声明的64K大很多,并且支持一维.二维或者三维纹理.在通用计算中,纹理存储器十分适合用于实现图像处理或查找表,并且对数据量较大时的随机数据访问或者非对齐访问也有良好的加速效果. 纹理存储器在硬件中并不对应一块专门的存储器,而实际上是牵涉到显存.两级纹理缓存.纹理抓取单

基于纹理内存的CUDA热传导模拟

原文链接 项目中有三个,第一个是全局内存,其余两个分别是基于1d和2d纹理内存.项目打包下载. 纹理内存是只读内存,与常量内存相同的是,纹理内存也缓存在芯片中,因此某些情况下,它能减少对内存的请求并提供更高效的内存宽带.纹理内存专门为那些内存访问模式中存在大量空间局部性的图形应用程序而设计的.在某个计算应用程序中,这意味着一个线程读取的位置可能与邻近线程读取的位置“非常接近”.纹理缓存为了加速访问不连续的地址而设计的. 温度计算的内存访问模式中存在着巨大的内存空间局部性,这种访问模式可以用GPU

CUDA零内存拷贝 疑问考证

今天思考了一下CUDA零内存拷贝的问题,感觉在即将设计的程序中会派上用场,于是就查了一下相关信息. 以下是一些有帮助的链接: cuda中的零拷贝用法--针对二维指针 cuda中的零拷贝用法--针对一维指针 cuda零拷贝用法-二维结构体指针 浅谈CUDA零拷贝内存 经过调查发现,零拷贝技术适用于集中计算.较少内存拷贝次数的问题.比如向量点积.求和运算等问题. 既然零拷贝技术是在CPU上开辟内存空间,GPU可以直接访问该空间,那么我就产生了一个疑问:"如果CPU上开辟的空间大于GPU的可用空间的时

CUDA共享内存的使用示例

CUDA共享内存使用示例如下:参考教材<GPU高性能编程CUDA实战>.P54-P65 教材下载地址:http://download.csdn.net/download/yizhaoyanbo/10150300.如果没有下载分可以评论区留下邮箱,我发你. 1 #include <cuda.h> 2 #include <cuda_runtime.h> 3 #include <device_launch_parameters.h> 4 #include <

CUDA线性内存分配

原文链接 概述:线性存储器可以通过cudaMalloc().cudaMallocPitch()和cudaMalloc3D()分配 1.1D线性内存分配 1 cudaMalloc(void**,int) //在设备端分配内存 2 cudaMemcpy(void* dest,void* source,int size,enum direction) //数据拷贝 3 cudaMemcpyToSymbol //将数据复制到__constant__变量中,或者__device__变量中 4 cudaMe

cuda学习3-共享内存和同步

为什么要使用共享内存呢,因为共享内存的访问速度快.这是首先要明确的,下面详细研究. cuda程序中的内存使用分为主机内存(host memory) 和 设备内存(device memory),我们在这里关注的是设备内存.设备内存都位于gpu之上,前面我们看到在计算开始之前,每次我们都要在device上申请内存空间,然后把host上的数据传入device内存.cudaMalloc()申请的内存,还有在核函数中用正常方法申请的变量的内存.这些内存叫做全局内存,那么还有没有别的内存种类呢?常用的还有共

CUDA Texture纹理存储器 示例程序

原文链接 1 /* 2 * Copyright 徐洪志(西北农林科技大学.信息工程学院). All rights reserved. 3 * Data: 2012-4-20 4 */ 5 // 6 // 此程序是演示了1D和2D纹理存储器的使用 7 #include <stdio.h> 8 #include <cutil_inline.h> 9 #include <iostream> 10 using namespace std; 11 12 texture<fl