Gpu_1_PNSR和SSIM优化

一Gpu模块介绍

Gpu有自己的存储叫做显存。当产生一个Mat对象时会存储到内存,这个对象由Cpu管理,这时Gpu并不能操作内存中的对象,Gpu只能操作分配在显存中的对象

1,基本类和函数

1>gpu::GpuMat类
相当于Mat
[1]不支持多维,只支持二维
[2]函数无法返回其引用
[3]没有表达式模板技术的支持

成员函数

//从m得到信息进行加载
void upload(const cv::Mat& m);
void upload(const CudaMem& m, Stream& stream);

//将信息保存到m
void download(cv::Mat& m) const;
void download(CudaMem& m, Stream& stream) const;

//exp:
Mat I1;         // 内存对象,可以用imread来创建
gpu::GpuMat gI; // GPU 矩阵 - 现在为空
gI1.upload(I1); //将内存数据上传到显存中

I1 = gI1;       //回传, gI1.download(I1) 也可以

很多时候,GPU函数只能接收单通道或者4通道的uchar或者float类型(CV_8UC1,CV_8UC4,CV_32FC1,CV_32FC4),GPU函数不支持双精度

如果函数只接收4通道或者单通道的图像而你的数据类型刚好是3通道的话,你能做的就是两件事:1.增加一个新的通道(使用char类型)或 2.将图像的三个通道切分为三个独立的图像,为每个图像调用该函数(推荐使用)。

2>gpu::Stream类
异步调用类

默认情况下,无论何时你调用一个GPU函数,系统都将等待调用完成并返回后继结果,这就意味着在GPU计算的时候CPU没干活。如果使异步调用,就会意味着它将调用后立即返回,并在后台异步执行,也就是说虽然CPU需要的数据还没从GPU返回,但是并不妨碍CPU进行其它的计算或者调用另一个函数。

可以异步进行类型转换,Mat与GpuMat,等其它操作

gpu::Stream stream;
//进行GpuMat的类型转换
stream.enqueueConvert(b.gI1, b.t1, CV_32F);   

3>操作函数
针对GpuMat,Gpu模块中对应了Cpu模块中的一部分操作函数,进行gpu操作时调用对应的函数

//进行异步通道分离
gpu::split(b.t1, b.vI1, stream);
//进行异步乘法              
gpu::multiply(b.vI1[i], b.vI1[i], b.I1_2, stream);        

2,操作原则

1>在现有对象上进行计算
在GPU中,任何小的数据传输都是一次大的开销,所以应该尽量避免不必要的数据传输。因此应该尽可能的在现有对象上计算(不创造新的显存对象)

//在下面的表达式中,会有一个隐性内存分配过程,调用乘法的结果必然要
//用一个临时对象储存,然后才能和*C1*相加
b.t1 = 2 * b.mu1_mu2 + C1;

//我们应该使用GPU处理函数代替算术表达式,
//从而避免额外创建不必要的临时对象
gpu::multiply(b.mu1_mu2, 2, b.t1); 
gpu::add(b.t1, C1, b.t1);

2>对gpu的对象尽量一次性分配完成

exp:
如果你需要创建一个调用多次的函数,

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值