OpenCL将数组从内存copy到显存
2018-06-17 23:12:51来源:未知 阅读 ()
本来想对上一篇博客做优化,优化效果不明显。但知识点还是要记一下。
初衷是想把上一篇博客中定义域的计算搬到CPU来计算,因为定义域的计算对于每一个kernel都是一样的,所以直接读取应该是可以进一步减小kernel的执行时间的。
我的思路的初衷是将这块的数据送到显存之后再送到寄存器中,从寄存器读取的时间应该是很快的,通过这样把计算的时间改为读取的时间。当然,读取寄存器的时间是否比计算更短,这个确实应该质疑,但是对于比较复杂的计算,我觉得直接读应该是比计算更快的。而对于这部分数据,CPU计算应该会比GPU更快。当然,还应当考虑数据量的大小,从内存搬到显存也是需要时间的。
1.C++代码
.................. int ksize = 11; float sigma_d = 3.0; float *dkl = new float[ksize*ksize]; for (int i = -ksize/2; i <= ksize/2; i++){ for (int j = -ksize/2; j <= ksize/2; j++){ dkl[(i+ksize/2)*ksize + (j+ksize/2)] = -(i*i + j*j) / (2 * 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, 0, ksize*ksize*sizeof(float), dkl, 0, NULL, NULL); ........................ errNum |= clSetKernelArg(kernel, 2, sizeof(cl_mem), &d_dkl); errNum |= clSetKernelArg(kernel, 3, 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(0); int y = (int)get_global_id(1); 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 = 0; 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 / 2; K <= ksize / 2; K++) { for (int L = -ksize / 2; L <= ksize / 2; L++) { fkl = read_imagef(src, sampler, (int2)(x + K, y + L)); rkl.x = -(fij.x - fkl.x)*(fij.x - fkl.x) / (2 * sigma_r*sigma_r); rkl.y = -(fij.y - fkl.y)*(fij.y - fkl.y) / (2 * sigma_r*sigma_r); rkl.z = -(fij.z - fkl.z)*(fij.z - fkl.z) / (2 * 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 > 0 && denominator.y > 0 && 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
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:1788:Pell数列
下一篇:3089:爬楼梯
- 纯虚函数与基类指针数组的运用 代码参考 2020-04-30
- STL之deque 2020-04-29
- C++基础 学习笔记六:复合类型之数组 2020-04-25
- c/c++ 使用valgrind检查内存泄漏 2020-04-14
- 寻找两个有序数组的中位数 2020-04-09
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash