本来想对上一篇博客做优化,优化效果不明显。但知识点还是要记一下。

初衷是想把上一篇博客中定义域的计算搬到CPU来计算,因为定义域的计算对于每一个kernel都是一样的,所以直接读取应该是可以进一步减小kernel的执行时间的。

我的思路的初衷是将这块的数据送到显存之后再送到寄存器中,从寄存器读取的时间应该是很快的,通过这样把计算的时间改为读取的时间。当然,读取寄存器的时间是否比计算更短,这个确实应该质疑,但是对于比较复杂的计算,我觉得直接读应该是比计算更快的。而对于这部分数据,CPU计算应该会比GPU更快。当然,还应当考虑数据量的大小,从内存搬到显存也是需要时间的。

1.C++代码

..................

int ksize = ;
float sigma_d = 3.0;
float *dkl = new float[ksize*ksize];
for (int i = -ksize/; i <= ksize/; i++){
for (int j = -ksize/; j <= ksize/; j++){
dkl[(i+ksize/)*ksize + (j+ksize/)] = -(i*i + j*j) / ( * sigma_d*sigma_d);
}
} cl_mem d_dkl;
d_dkl = clCreateBuffer(context, CL_MEM_READ_ONLY, ksize*ksize*sizeof(float), NULL,NULL);
clEnqueueWriteBuffer(commandQueue, d_dkl, CL_TRUE, , ksize*ksize*sizeof(float), dkl, , NULL, NULL); ........................ errNum |= clSetKernelArg(kernel, , sizeof(cl_mem), &d_dkl);
errNum |= clSetKernelArg(kernel, , sizeof(cl_mem), &ksize); ........................ delete[] dkl; ...................

主要就是clCreateBuffer函数和clEnqueueWriteBuffer函数的用法。

2.kernel代码

const sampler_t sampler = CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST;

kernel void bilateralBlur(read_only image2d_t src, write_only image2d_t dst, __constant float* dkl, int ksize)
{
int x = (int)get_global_id();
int y = (int)get_global_id();
if (x >= get_image_width(src) || y >= get_image_height(src))
return; float sigma_d = 3.0;
float sigma_r = 0.1; float4 fij = read_imagef(src, sampler, (int2)(x, y)); float alpha = 0.2;
float4 fkl;
float4 rkl;
float4 wkl; int index = ; float4 numerator = (float4)(0.0f,0.0f,0.0f,0.0f);
float4 denominator = (float4)(1.0f, 1.0f, 1.0f, 1.0f);
for (int K = -ksize / ; K <= ksize / ; K++)
{
for (int L = -ksize / ; L <= ksize / ; L++)
{
fkl = read_imagef(src, sampler, (int2)(x + K, y + L)); rkl.x = -(fij.x - fkl.x)*(fij.x - fkl.x) / ( * sigma_r*sigma_r);
rkl.y = -(fij.y - fkl.y)*(fij.y - fkl.y) / ( * sigma_r*sigma_r);
rkl.z = -(fij.z - fkl.z)*(fij.z - fkl.z) / ( * sigma_r*sigma_r); wkl.x = exp(-dkl[index] + rkl.x);
wkl.y = exp(-dkl[index] + rkl.y);
wkl.z = exp(-dkl[index] + rkl.z);
index++; numerator.x += fkl.x * wkl.x;
numerator.y += fkl.y * wkl.y;
numerator.z += fkl.z * wkl.z; denominator.x += wkl.x;
denominator.y += wkl.y;
denominator.z += wkl.z;
}
} float4 gij = (float4)(0.0f, 0.0f, 0.0f, 1.0f);
if (denominator.x > && denominator.y > && denominator.z)
{
gij.x = numerator.x / denominator.x;
gij.y = numerator.y / denominator.y;
gij.z = numerator.z / denominator.z; gij.x = fij.x*alpha + gij.x*(1.0 - alpha);
gij.y = fij.y*alpha + gij.y*(1.0 - alpha);
gij.z = fij.z*alpha + gij.z*(1.0 - alpha);
} write_imagef(dst, (int2)(x, y), gij);
}

与上一博客的代码相比,主要就是把dkl的计算改为了读取,ksize也通过参数传进来。

3.结果

与上一篇3.42ms相比,有零点几毫秒的优化。不过考虑CPU的计算,优化应该更小,或者没有,或者稍差。

当然,我这里的计算简单,对于复杂的计算,应该还是可以考虑这种优化方法的。

下一步考虑内存优化,增大粒度。

代码:http://download.csdn.net/download/qq_33892166/9771206

OpenCL将数组从内存copy到显存的更多相关文章

  1. 深度学习中GPU和显存分析

    刚入门深度学习时,没有显存的概念,后来在实验中才渐渐建立了这个意识. 下面这篇文章很好的对GPU和显存总结了一番,于是我转载了过来. 作者:陈云 链接:https://zhuanlan.zhihu. ...

  2. OpenGL8-直接分配显存-极速绘制(Opengl1.5版本才有)

    视频教程请关注 http://edu.csdn.net/lecturer/lecturer_detail?lecturer_id=440 /** * 这个例子介绍如何使用显卡内存进行绘制 下载地址 : ...

  3. 自制操作系统Antz(3)——进入保护模式 (中) 直接操作显存

    Antz系统更新地址: https://www.cnblogs.com/LexMoon/category/1262287.html Linux内核源码分析地址:https://www.cnblogs. ...

  4. Mac更改显存

    今天尝试了 发现很有效果 不敢独享 所以贴一下,如果我火星了 ..就无视我吧 问题表现为: 1. 随机出现花屏,和 横线. 随机出现死机2. 随着再次渲染(例如桌面背景切换),花屏或横线会消失3. 当 ...

  5. Java数组及其内存分配

    几乎所有的程序设计语言都支持数组.Java也不例外.当我们需要多个类型相同的变量的时候,就考虑定义一个数组.在Java中,数组变量是引用类型的变量,同时因为Java是典型的静态语言,因此它的数组也是静 ...

  6. 《疯狂Java:突破程序员基本功的16课》读书笔记-第一章 数组与内存控制

    很早以前就听过李刚老师的疯狂java系列很不错,所以最近找一本拿来拜读,再此做下读书笔记,促进更好的消化. 使用Java数组之前必须先对数组对象进行初始化.当数组的所有元素都被分配了合适的内存空间,并 ...

  7. Java数组的内存管理

    Java数组的内存管理 Java语言是典型的静态语言,因此Java的数组是静态的,即当数组被初始化之后,该数组的长度是不可变的.Java程序中的数组必须经初始化才能使用.所谓初始化,就是当数组对象的元 ...

  8. gpu显存(全局内存)在使用时数据对齐的问题

    全局存储器,即普通的显存,整个网格中的随意线程都能读写全局存储器的任何位置. 存取延时为400-600 clock cycles  很easy成为性能瓶颈. 訪问显存时,读取和存储必须对齐,宽度为4B ...

  9. 数组的strong copy理解

      一.数组的不同情况下的copy,mutablecopy分析 1.不可变数组的copy(没有创建新对象,复制的只是指针)       2.不可变数组的mutable copy(创建新对象)     ...

随机推荐

  1. Python 新手常犯错误(第一部分)转载

    觉得这篇文章针对python的默认参数写的不错,翻译的也不错,故转载下. 原文链接: Amir Rachum   翻译: 伯乐在线- 伯乐在线读者译文链接: http://blog.jobbole.c ...

  2. PEP8编码规范

    1.代码布局设计 1.1 缩进 -4个空格进行缩进 1.2 tab键-在python2中tab和空格是混用的,但是在python中基本上使用tab(pycharm开发工具会自动对代码缩进) 1.3 最 ...

  3. 编译安装MariaDB-10.0.21

    一.源码编译安装gcc-5.1.0 1.下载gcc源码包 Download (HTTP): http://ftpmirror.gnu.org/gcc/gcc-5.2.0/gcc-5.2.0.tar.b ...

  4. Teleport Ultra 垃圾代码 tppabs的清理<转>

    在使用整站下载软件Teleport Pro或Teleport Ultra下载的离线文件里会包含大量垃圾代码,下载后就需要清除整站下载文件中的冗余代码:tppabs等.这些代码本是Teleport自动添 ...

  5. Dom与Bom,增删改查

    对Web标准的理解:web标准是由一系列标准组合而成的,页面有三个部分组成:结构,表现和行为.因而web标准即由结构化标准语言主要有 xml和xhtml,表现标准语言css,行为标准主要包括对象模型( ...

  6. maven安装配置参数化打包命令

    Maven使用 maven的配置文件看似很复杂,其实只需要根据项目的实际背景,设置个别的几个配置项而已.maven有自己的一套默认配置,使用者除非必要,并不需要去修改那些约定内容.这就是所谓的“约定优 ...

  7. mysql中explain的用法

    mysql中explain的用法 最近在做性能测试中经常遇到一些数据库的问题,通常使用慢查询日志可以找到执行效果比较差的sql,但是仅仅找到这些sql是不行的,我们需要协助开发人员分析问题所在,这就经 ...

  8. 让boost.variant支持lambda表达式访问

    前言 之前写个过一篇博客叫<浅谈boost.variant的几种访问方式>,里面讲到了可以通过访问者方式来获取variant的值,但是在重载函数operator()里面只能够获取varia ...

  9. CentOS6.5安装Qt4.8.6+QtCreator2.6.1

    工作中需要用到Qt在Linux下做开发,公司提供的电脑安装的CentOS6.2,但是为了和windows下自己使用的QT版本一直,于是也选择安装了Qt5.1.0.但是在CentOS下刚开始是无法启动, ...

  10. 20145310《Java程序设计》第3周学习总结

    20145310 <Java程序设计>第3周学习总结 教材学习内容总结 本周学习内容比较多,主要是第四第五章的学习. 第四章 类与对象 类是对象的设计图,对象是类的实例. 类(Class) ...