cuda报告

课 程 设 计

题目: CUDA加速和优化直方图均衡化

姓 名: nch

学 号: SA19219093

学 院: 微电子学院

学校:中国科学技术大学
专 业: 集成电路

指导教师: 谭立湘

2019 年 12 月 15 日

CUDA加速和优化直方图均衡化

项目简介

直方图均衡化(Histogram Equalization) 又称直方图平坦化,实质上是对图像进行非线性拉伸,重新分配图像象元值,使一定灰度范围内象元值的数量大致相等。直方图均衡化的只要目的是为了图像的增强。在现实的拍摄过程中,比如说视频监控领域,由于其图像的灰度分布集中在较窄的范围内,这就导致了图像的细节不够清晰。为什么不清晰呢,因为灰度分布较窄时,在计算对比度的时候,对比度就很小,所以就不清晰。为了使得图像变得清晰,那么就需要使得灰度值的差别变大,为了使得灰度值的差别变大,就意味着灰度分布就变的较宽,使得灰度值分布变得均匀,在某个灰度级区间内,像素的个数分布大致相同,这样才能使得图像的对比度增强,细节变得清晰可见。直方图均衡化就是对图像进行非线性拉伸,使得变换后的图像直方图分布均匀。

基于 GPU 课程学习的基础上,采用 CUDA 编程对直方图均衡化加速和优化,利用 GPU 的高度并发性能,提高对图片处理的速度。设计中实现了直方图灰度的统计,灰度占比的计算,直方图概率累积,灰度映射,并且在 GPU 实现和 CPU 实现进行了对比实验。

关键词:CUDA,直方图均衡化,共享内存,原子操作

2

目录

1.CUDA简介… 4

   1.1 CUDA编程................................................................................................................. 4

1.1.1 CUDA的执行模型… 4

       1.2.1 常用函数及用法........................................................................................... 4

   1.2 软件配置.................................................................................................................... 5

   1.3 硬件配置.................................................................................................................... 5
  1. 基础知识… 6

    2.1 共享内存… 6

    2.2 原子操作---------------------------------------------------------------------------------------------- 6

    2.3 规约操作… 6

  2. CPU源程序… 8

    3.1 直方图灰度的统计… 8

    3.2 灰度图占比的计算… 8

    3.3 直方图概率的累积… 9

    3.4 灰度的映射… 9

    3.5 实验结果测试… 10

  3. GPU加速优化… 11

4.1 直方图灰度统计的优化… 11

4.2 灰度占比的优化… 11

4.3 直方图概率累积的优化… 12

4.4 灰度映射的优化… 13

  1. 对比分析… 14

  2. 总结… 15

3

1.CUDA简介

1.1CUDA 编程

1.1.1 CUDA 的执行模型

在 CUDA
的架构下,一个程序分为两个部份:host
端和
device 端。Host 端是指在 CPU 上执行的部份,而 device 端则是在显示芯片上执行的部份。Device

端的程序又称为 kernel。通常 host 端程序会将数据准备好后,复制到显卡的内

存中,再由显示芯片执行 device 端程序,完成后再由 host 端程序将结果从显卡

的内存中取回。一个完整的 CUDA 程序是由一系列的设备端 kernel 核函数并行

步骤和主机端串行处理步骤共同组成的。在这个模型中,CPU 与 GPU 协同工作,

CPU
负责进行逻辑性强的事物处理和串行计算,GPU
则专注于执行高度线程化

的并形处理任务。

Kernel
不是一个完整的程序,而只是其中的一个关键并行计算步骤。Kernel

以一个网格(Grid)的形式,每个网格由若干个线程块(block)组成,每一个线

程块又由若干个线程(thread)组成。

1.1.2 常用函数及用法

(1)核函数的声明与执行

要写在显示芯片上执行的程序。在 CUDA 中,在函数前面加上__global__表

示这个函式是要在显示芯片上执行的。在显示芯片上执行的程序有一些限制,首

先最明显的一个限制,不能有传回值,一般把计算结构返回值写在函数的指针类

型参数中。

在 CUDA 中,要执行一个核函数,可以使用语法:

函数名称<<<block
数目,
thread 数目, shared memory 大小>>>(参数…);

(2)全局内存的使用

GPU 的全局内存之所以是全局内存,主要是因为 GPU 与 CPU 都可以对它进

行写操作,任何设备都可以通过 PCI-E 总线对其进行访问。在多 GPU 系统GPU 之间可以不通过 CPU 直接将数据从一块 GPU 卡传输到另一块 GPU 卡上。使用 cudaMalloc 函数开辟一块全局内存空间。使用 cudaMemcpy
函数可以把 CPU 上的数据传输到 GPU 的全局内存上或者相反方向。

4

1.2软件配置

在win10
系统上完成 CUDA8.0 的安装:

在win10
系统上安装opencv3.4.0

在win10
系统上安装 Visual Studio 2015。

1.3 硬件配置

处理器:Intel®
Core™ i5-8500U CPU @ 3.00GHz 3.00GHz,RAM: 8.00GB

显卡:Intel® HD
Graphics Family

NVIDIA
GeForce GT 730

5

2.基础知识

2.1 共享内存

    ShareMemory(共享内存) 是一个 block 中所有thread 都能使用的共享内存,存取的速度相当快,存取

shared memory 的速度和存取寄存器相同,不需要担心 latency
的问题。原理上来说,共享内存是GPU上可受用户控制的一级缓存。在一个SM中,存在着若干cuda core + DP(双精度计算单元) + SFU(特殊函数计算单元)+共享内存+常量内存+纹理内存。因而共享内存的使用时性能提高的一个重要的因素。但是注意到,将数据拷贝到共享内存中也消耗了部分时间。因而,共享内存仅仅适合存在着数据的重复利用,全局的内存合并或者是线程之间有共享数据的时候,否则直接使用全局内存会更好一些。

2.2原子操作

原子操作 是指对全局和共享内存中的32位或者64位数据进行 “读取-修改-覆写”这一操作。原子操作可以看作是一种最小单位的执行过程。
在其执行过程中,不允许其他并行线程对该变量进行读取和写入的操作。 如果发生竞争,则其他线程必须等待。原子操作只支持某些运算(加、减、最小值、异或运算等,不支持求余和求幂等)和数据类型(整型),但是需要注意的是,原子操作的运行顺序不定,如果安排不当的话,会使速度变慢。

2.3规约操作

规约是一类并行算法,对传入的N个数据,使用一个二元的符合结合律的操作符⊕,生成1个结果。这类操作包括取最小、取最大、求和、平方和、逻辑与/或、向量点积。规约也是其他高级算法中重要的基础算法。除非操作符⊕的求解代价极高,否则规约倾向于带宽受限型任务(bandwidthbound)。本文将介绍几种规约算法的实现,从两遍规约、block的线程数必须为2的幂,一步一步优化到单遍规约、任意线程数的规约实现,还将讨论讨论基于C++模板的优化。

6

7

3.CPU源程序

3.1 直方图灰度的统计

               我们要处理的图像是灰度图像,如果是彩色的,需要先转化成灰度图像,然 

后确定图像的灰度级有多大,一般就是8位的图像,灰度级为0-255。利用opencv

加载图像并且转换成灰度图。

对灰度图进行直方图的统计。

3.2 灰度图占比的计算

8

3.3 直方图概率的累积

3.4 灰度的映射

9

3.5 实验结果测试

 输入原图:

    



   直方图均衡化的图:

10

4.GPU 加速优化

4.1 直方图灰度的统计的优化

 开辟一段共享内存,数据在共享内存的读写速度大于在全局内存的读写速度。同时,保证输出结果的正确性,使用原子操作。开辟的线程数为16×16.

4.2 灰度图占比的计算的优化

            在一个block中,开辟256个线程,并行计算得到概率。。

11

4.3 直方图概率累积的优化

对概率进行累加,可以采用并行规约算法,提高累加的速度。

12

4.4 灰度的映射优化

13

5.对比分析

GPU 与 CPU 运行时间的对比

输入十张不同大小的图片进行结果对比,并且每个图片运行十遍。

输入的图像大小:800×534

输入的图像大小:500×413

输入的图像大小:576×324

输入的图像大小:3584×2016

输入的图像大小:720×480

输入的图像大小:1920×1080

输入的图像大小:2560×1600

输入的图像大小:1920×1200

输入的图像大小:3840×2160

14

图片的大小

CPU运行时间

GPU运行时间

加速比

800×534

34.4907ms

1.1950ms

28.86

500×413

30.8715ms

2.96653ms

10.40

576×324

10.9619ms

1.377280ms

7.96

3584×2016

116.913ms

4.320256

27.06

720×480

64.2778ms

1.045504ms

61.480

1920×1080

109.867ms

1.959936ms

56.056

2560×1600

121.166ms

2.969600ms

40.8021

1920×1200

110.219ms

1.956864ms

56.3243

3840×2160

117.654ms

5.150720ms

22.8422

通过上述简单的实验,可以得出随着图片变大,CPU上运行的时间越长,加速比越来越大。由于时间有限,我自己认为应该比较使用全局内存和共享内存下实验结果的区别,同时利用不同的Block和Thread进行对比,在写报告的时,发现新的优化方法,来不及进行实验。但是,上述实验说明对串行程序起到了一定程度上的加速优化作用。

6.总结

通过测试对比,可以发现在GPU上使用共享内存,原子操作和规约加法的优化加速方法,可以较为显著的提高性能。由于时间有限,在实验的对比上做法有些粗糙。为了提高实验的准确性,应该考虑在全局内存下和共享内存的实验对比,也可以实验不用规约和用规约的区别,开辟不同数量的Block和Thread进行测试。同时,从学习的过程中,我发现可以有更好的优化方法,例如使用纹理内存或者常量内存。虽然这次报告写的较为粗糙,但是实验结果还是在一定程度上具有可靠性。

通过这次课程设计,我学到了很多,不仅仅是对上课知识的系统回顾和总结,从同学报告中有了新的知识,得到新的启发。更为重要的是,燃起了我对GPU开发的浓厚兴趣,对以前的编写的开发代码和编程知识有了新的思考,冥冥之中发现新天地,并且希望更加深入学习GPU的开发。在此,衷心感谢老师默默付出,和上课同学对我潜移默化的影响和帮助。

15

课 程 设 计

题目: CUDA加速和优化直方图均衡化

姓 名: 倪长好

学 号: SA19219093

学 院: 微电子学院

专 业: 集成电路

指导教师: 谭立湘

2019 年 12 月 15 日

1

CUDA加速和优化直方图均衡化

项目简介

直方图均衡化(Histogram Equalization) 又称直方图平坦化,实质上是对图像进行非线性拉伸,重新分配图像象元值,使一定灰度范围内象元值的数量大致相等。直方图均衡化的只要目的是为了图像的增强。在现实的拍摄过程中,比如说视频监控领域,由于其图像的灰度分布集中在较窄的范围内,这就导致了图像的细节不够清晰。为什么不清晰呢,因为灰度分布较窄时,在计算对比度的时候,对比度就很小,所以就不清晰。为了使得图像变得清晰,那么就需要使得灰度值的差别变大,为了使得灰度值的差别变大,就意味着灰度分布就变的较宽,使得灰度值分布变得均匀,在某个灰度级区间内,像素的个数分布大致相同,这样才能使得图像的对比度增强,细节变得清晰可见。直方图均衡化就是对图像进行非线性拉伸,使得变换后的图像直方图分布均匀。

基于 GPU 课程学习的基础上,采用 CUDA 编程对直方图均衡化加速和优化,利用 GPU 的高度并发性能,提高对图片处理的速度。设计中实现了直方图灰度的统计,灰度占比的计算,直方图概率累积,灰度映射,并且在 GPU 实现和 CPU 实现进行了对比实验。

关键词:CUDA,直方图均衡化,共享内存,原子操作

2

目录

1.CUDA简介… 4

   1.1 CUDA编程................................................................................................................. 4

1.1.1 CUDA的执行模型… 4

       1.2.1 常用函数及用法........................................................................................... 4

   1.2 软件配置.................................................................................................................... 5

   1.3 硬件配置.................................................................................................................... 5
  1. 基础知识… 6

    2.1 共享内存… 6

    2.2 原子操作---------------------------------------------------------------------------------------------- 6

    2.3 规约操作… 6

  2. CPU源程序… 8

    3.1 直方图灰度的统计… 8

    3.2 灰度图占比的计算… 8

    3.3 直方图概率的累积… 9

    3.4 灰度的映射… 9

    3.5 实验结果测试… 10

  3. GPU加速优化… 11

4.1 直方图灰度统计的优化… 11

4.2 灰度占比的优化… 11

4.3 直方图概率累积的优化… 12

4.4 灰度映射的优化… 13

  1. 对比分析… 14

  2. 总结… 15

3

1.CUDA简介

1.1CUDA 编程

1.1.1 CUDA 的执行模型

在 CUDA
的架构下,一个程序分为两个部份:host
端和
device 端。Host 端是指在 CPU 上执行的部份,而 device 端则是在显示芯片上执行的部份。Device

端的程序又称为 kernel。通常 host 端程序会将数据准备好后,复制到显卡的内

存中,再由显示芯片执行 device 端程序,完成后再由 host 端程序将结果从显卡

的内存中取回。一个完整的 CUDA 程序是由一系列的设备端 kernel 核函数并行

步骤和主机端串行处理步骤共同组成的。在这个模型中,CPU 与 GPU 协同工作,

CPU
负责进行逻辑性强的事物处理和串行计算,GPU
则专注于执行高度线程化

的并形处理任务。

Kernel
不是一个完整的程序,而只是其中的一个关键并行计算步骤。Kernel

以一个网格(Grid)的形式,每个网格由若干个线程块(block)组成,每一个线

程块又由若干个线程(thread)组成。

1.1.2 常用函数及用法

(1)核函数的声明与执行

要写在显示芯片上执行的程序。在 CUDA 中,在函数前面加上__global__表

示这个函式是要在显示芯片上执行的。在显示芯片上执行的程序有一些限制,首

先最明显的一个限制,不能有传回值,一般把计算结构返回值写在函数的指针类

型参数中。

在 CUDA 中,要执行一个核函数,可以使用语法:

函数名称<<<block
数目,
thread 数目, shared memory 大小>>>(参数…);

(2)全局内存的使用

GPU 的全局内存之所以是全局内存,主要是因为 GPU 与 CPU 都可以对它进

行写操作,任何设备都可以通过 PCI-E 总线对其进行访问。在多 GPU 系统GPU 之间可以不通过 CPU 直接将数据从一块 GPU 卡传输到另一块 GPU 卡上。使用 cudaMalloc 函数开辟一块全局内存空间。使用 cudaMemcpy
函数可以把 CPU 上的数据传输到 GPU 的全局内存上或者相反方向。

4

1.2软件配置

在win10
系统上完成 CUDA8.0 的安装:

在win10
系统上安装opencv3.4.0

在win10
系统上安装 Visual Studio 2015。

1.3 硬件配置

处理器:Intel®
Core™ i5-8500U CPU @ 3.00GHz 3.00GHz,RAM: 8.00GB

显卡:Intel® HD
Graphics Family

NVIDIA
GeForce GT 730

5

2.基础知识

2.1 共享内存

    ShareMemory(共享内存) 是一个 block 中所有thread 都能使用的共享内存,存取的速度相当快,存取

shared memory 的速度和存取寄存器相同,不需要担心 latency
的问题。原理上来说,共享内存是GPU上可受用户控制的一级缓存。在一个SM中,存在着若干cuda core + DP(双精度计算单元) + SFU(特殊函数计算单元)+共享内存+常量内存+纹理内存。因而共享内存的使用时性能提高的一个重要的因素。但是注意到,将数据拷贝到共享内存中也消耗了部分时间。因而,共享内存仅仅适合存在着数据的重复利用,全局的内存合并或者是线程之间有共享数据的时候,否则直接使用全局内存会更好一些。

2.2原子操作

原子操作 是指对全局和共享内存中的32位或者64位数据进行 “读取-修改-覆写”这一操作。原子操作可以看作是一种最小单位的执行过程。
在其执行过程中,不允许其他并行线程对该变量进行读取和写入的操作。 如果发生竞争,则其他线程必须等待。原子操作只支持某些运算(加、减、最小值、异或运算等,不支持求余和求幂等)和数据类型(整型),但是需要注意的是,原子操作的运行顺序不定,如果安排不当的话,会使速度变慢。

2.3规约操作

规约是一类并行算法,对传入的N个数据,使用一个二元的符合结合律的操作符⊕,生成1个结果。这类操作包括取最小、取最大、求和、平方和、逻辑与/或、向量点积。规约也是其他高级算法中重要的基础算法。除非操作符⊕的求解代价极高,否则规约倾向于带宽受限型任务(bandwidthbound)。本文将介绍几种规约算法的实现,从两遍规约、block的线程数必须为2的幂,一步一步优化到单遍规约、任意线程数的规约实现,还将讨论讨论基于C++模板的优化。

6

7

3.CPU源程序

3.1 直方图灰度的统计

               我们要处理的图像是灰度图像,如果是彩色的,需要先转化成灰度图像,然 

后确定图像的灰度级有多大,一般就是8位的图像,灰度级为0-255。利用opencv

加载图像并且转换成灰度图。

对灰度图进行直方图的统计。

3.2 灰度图占比的计算

8

3.3 直方图概率的累积

3.4 灰度的映射

9

3.5 实验结果测试

 输入原图:

    



   直方图均衡化的图:

10

4.GPU 加速优化

4.1 直方图灰度的统计的优化

 开辟一段共享内存,数据在共享内存的读写速度大于在全局内存的读写速度。同时,保证输出结果的正确性,使用原子操作。开辟的线程数为16×16.

4.2 灰度图占比的计算的优化

            在一个block中,开辟256个线程,并行计算得到概率。。

11

4.3 直方图概率累积的优化

对概率进行累加,可以采用并行规约算法,提高累加的速度。

12

4.4 灰度的映射优化

13

5.对比分析

GPU 与 CPU 运行时间的对比

输入十张不同大小的图片进行结果对比,并且每个图片运行十遍。

输入的图像大小:800×534

输入的图像大小:500×413

输入的图像大小:576×324

输入的图像大小:3584×2016

输入的图像大小:720×480

输入的图像大小:1920×1080

输入的图像大小:2560×1600

输入的图像大小:1920×1200

输入的图像大小:3840×2160

14

图片的大小

CPU运行时间

GPU运行时间

加速比

800×534

34.4907ms

1.1950ms

28.86

500×413

30.8715ms

2.96653ms

10.40

576×324

10.9619ms

1.377280ms

7.96

3584×2016

116.913ms

4.320256

27.06

720×480

64.2778ms

1.045504ms

61.480

1920×1080

109.867ms

1.959936ms

56.056

2560×1600

121.166ms

2.969600ms

40.8021

1920×1200

110.219ms

1.956864ms

56.3243

3840×2160

117.654ms

5.150720ms

22.8422

通过上述简单的实验,可以得出随着图片变大,CPU上运行的时间越长,加速比越来越大。由于时间有限,我自己认为应该比较使用全局内存和共享内存下实验结果的区别,同时利用不同的Block和Thread进行对比,在写报告的时,发现新的优化方法,来不及进行实验。但是,上述实验说明对串行程序起到了一定程度上的加速优化作用。

6.总结

通过测试对比,可以发现在GPU上使用共享内存,原子操作和规约加法的优化加速方法,可以较为显著的提高性能。由于时间有限,在实验的对比上做法有些粗糙。为了提高实验的准确性,应该考虑在全局内存下和共享内存的实验对比,也可以实验不用规约和用规约的区别,开辟不同数量的Block和Thread进行测试。同时,从学习的过程中,我发现可以有更好的优化方法,例如使用纹理内存或者常量内存。虽然这次报告写的较为粗糙,但是实验结果还是在一定程度上具有可靠性。

通过这次课程设计,我学到了很多,不仅仅是对上课知识的系统回顾和总结,从同学报告中有了新的知识,得到新的启发。更为重要的是,燃起了我对GPU开发的浓厚兴趣,对以前的编写的开发代码和编程知识有了新的思考,冥冥之中发现新天地,并且希望更加深入学习GPU的开发。在此,衷心感谢老师默默付出,和上课同学对我潜移默化的影响和帮助。

15

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值