卷积操作的GPU粗粒度并行实现及测试

一、    算法基本思想:

1、           GPU中的一个线程产生一个卷积结果,有多少个结果就使用多少个Block;

2、           矩阵和卷积核存放在共享内存中,卷积结果存放在全局内存中;

3、           支持10000以内任意维度的二维矩阵,卷积核最大支持16x16。

4、           支持任意多幅图像的批处理。

二、    实验平台:

CPU:Intel(R) Xeon(R) E5-2650 0 @2.00GHz 16核 32线程

GPU:NVIDIA Tesla C2070(见下表)

RAM Memory:64G

Operating System:64bit Win7。


尺寸规格


9.75英寸PCIe x16规格


Tesla GPU的数量


1


CUDA核心数量


448


CUDA核心频率


1.15 GHz


双精度浮点性能(峰值)


515 Gflops


单精度浮点性能(峰值)


1.03 Tflops


专用存储器总容量*

Tesla C2050

Tesla C2070


3GB GDDR5

6GB GDDR5


存储器频率


1.5 GHz


存储器接口


384位


存储器带宽


144 GB/秒


功耗

Tesla C2050


238W热设计功耗


系统接口


PCIe x16 Gen2


散热解决方案


主动式风扇散热器


显示器支持

Dual-Link DVI-I

显示器最大分辨率@ 60Hz


1

2560x1600


软件开发工具


CUDA C/C++/Fortran、OpenCL以及DirectCompute工具包。

针对Visual Studio的NVIDIA?(英伟达?)Parallel Nsight?

三、    CPU和GPU耗时比较

      说明:在CPU实现中,不做任何优化,卷积操作使用基本的四层循环形式。为了程序了通用性,在GPU内部做了很多的条件测试,比较耗时。这个是初始版,可以做进一步优化,比如一些字节对齐等。

测试时间说明:使用clock()进行测试,精度为0.001秒(1ms),GPU测试的总时间包括函数调度开销、GPU启动开销、设备内存的申请释放开销、数据传输开销和计算开销等,并且测试了数据的预处理和后处理的时间消耗。CPU只有函数调度开销和计算开销。

误差说明:CPU和GPU均使用float型数组存储数据,矩阵和卷积核数据随机初始化,并对CPU和GPU卷积结果作比较,测试卷积的有效性。

初步分析:

A.    CPU和GPU卷积结果误差为0,表明GPU实现是有效的。

B.     矩阵和卷积核较小时,CPU性能较好。矩阵和卷积核较大时,GPU性能较高,体现出GPU的并行性,能快速处理大规模、高吞吐量的数据。当数据量不是很大时,GPU耗时主要是启动开销,即设备内存的分配开销。

C.     GPU上,一个线程产生一个卷积结果,在线程内部是串行的,卷积核越大,单个卷积结果越耗时。

为了减少访问全局内存的次数,运算前,矩阵和卷积核拷贝到Block内部的共享内存中。

使用二维Block,一个Block内部16x16个线程,产生多少个卷积结果就使用多少个Block,因此固定卷积核,改变矩阵大小,运行时间基本不变,当矩阵过大时,使用的Block数量过多时,运算时间受限于GPU硬件中支持的SM和Block数量。(考虑卷积程序的通用性,数据拷贝时使用了比较多的条件测试和分支操作,性能受一定影响)。

D.    CPU上是简单的串行运算,受矩阵和卷积核大小影响较大。

E.     当矩阵两个维度都超过10000时,CPU运算出现指针异常,可能是矩阵较大时(550MB左右),数据存储时不再连续,指针溢出。所以无法测试。


Matrix Size


Number


Kernel


CPU(s)


CPU2GPU


GPU-Kernel


GPU2CPU


5x4


1


5x4


<1ms


<1ms


<1ms


<1ms


12x9


1


5x4


<1ms


<1ms


<1ms


<1ms


18x19


1


5x4


<1ms


<1ms


<1ms


<1ms


118x29


1


5x4


<1ms


<1ms


<1ms


<1ms


138x59


1


5x4


<1ms


<1ms


<1ms


<1ms


158x159


1


5x4


0.003


<1ms


0.001


<1ms


558x559


1


5x4


0.044


0.001


0.001


<1ms


1128x1159


1


5x4


0.157


0.002


0.004


0.001


2128x2159


1


5x4


0.442


0.007


0.012


0.007


5128x5159


1


5x4


2.394


0.038


0.068


0.035


18128x4159


1


5x4


6.866


0.111


0.193


0.114


10128x11159


1


5x4


10.074


0.160


0.288


0.142


15.54Gflops


1.427GBps


5x4


1


14x15


~


~


~


~


12x9


1


14x15


~


~


~


~


18x19


1


14x15


<1ms


<1ms


<1ms


<1ms


118x29


1


14x15


<1ms


<1ms


<1ms


<1ms


138x59


1


14x15


<1ms


0.001


<1ms


<1ms


158x159


1


14x15


0.024


<1ms


<1ms


<1ms


558x559


1


14x15


0.354


<1ms


0.006


0.001


1128x1159


1


14x15


1.400


0.002


0.023


0.002


2128x2159


1


14x15


3.839


0.007


0.082


0.007


5128x5159


1


14x15


22.856


0.042


0.475


0.035


11128x4159


1


14x15


38.172


0.079


0.833


0.061


10128x11159


1


14x15


122.679


0.203


2.614


0.358


23.23Gflops


382.6MBps


5x4


15


14x15


~


~


~


~


12x9


15


14x15


~


~


~


~


18x19


15


14x15


0.001


<1ms


<1ms


<1ms


118x29


15


14x15


0.041


<1ms


0.001


<1ms


138x59


15


14x15


0.097


<1ms


0.002


<1ms


158x159


15


14x15


0.372


0.001


0.007


<1ms


558x559


15


14x15


4.943


0.006


0.084


0.006


1128x1159


15


14x15


15.851


0.030


0.353


0.028


2128x2159


15


14x15


57.699


0.097


1.247


0.084


3158x3059


15


14x15


121.152


0. 201


2.624


0.192


5128x5159


15


14x15


指针溢出


11128x4159


15


14x15


10128x11159


15


14x15


23.01Gflops


362.9MBps

进一步分析:

从上表可知,最高吞吐率为1.427GBps,PCAIE总线的带宽为5GBps,还有一定的空间。单精度浮点数乘法的最高有效计算性能为23.23Gflops,官方文档上标示的最高单精度浮点性能为1Tflops,差别较大,分析原因如下:

A.    CPU传输给GPU的数据是一维数组,而在GPU内部是按二维进行运算的,在存取数据是需要做很多的地址计算操作。

B.     由于卷积特有的性质,数据有很多的重复性,将大图像分割成很多小的图像块时,需要考虑边界问题,并且为了保证程序的通用性,支持任意的图像和卷积核大小,以及支持任意多幅图像的批处理,GPU中,将数据拷贝到共享内存之前,做了比较多的条件测试,时间消耗比较大。这个地方可以通过在CPU进行边界扩展等预处理,进一步提高GPU运算性能。

C.     线程内部计算单个卷积结果时,使用了一个二维循环,当卷积核较大时,运算时间呈指数型增长。

总结:

写一个GPU程序简单,写一个高效的GPU程序难,而写一个高效的通用性的GPU程序,更难,需要考虑方方面面的东西。目前版本的程序,仅仅具有简单的通用性,因为使用基本的数据结构保存数据,当数据量达到500MB时,很容易出现问题,而且计算效率也不是很高。

下周工作计划:

(1)       在CPU中做一些数据的预处理,考虑字节对齐,边界填充等,尽量减少GPU内部的条件测试。考虑将单个的卷积操作拆开,实现细粒度并行,提高单个卷积结果的计算效率。

(2)       学习三维Block,将一幅图像放在第一和第二维度上,批处理图像放在第三个维度,减少后处理计算量,增加批处理图像的卷积计算性能。

(3)       考虑反卷积运算的并行化。考虑将CUDA卷积程序与matlab版的CNN结合,进行交叉编译,提高CNN的运算效率。

时间: 2024-10-25 04:41:22

卷积操作的GPU粗粒度并行实现及测试的相关文章

卷积操作的GPU粗粒度并行实现及测试(优化)

A.边界扩展: B.字块对齐. Matrix Size Number Kernel CPU(s) CPU2GPU GPU-Kernel GPU2CPU 5x4 1 5x4 <1ms <1ms <1ms <1ms 12x9 1 5x4 <1ms <1ms <1ms <1ms 18x19 1 5x4 <1ms <1ms <1ms <1ms 118x29 1 5x4 <1ms <1ms <1ms <1ms 138x5

深度神经网络DNN的多GPU数据并行框架 及其在语音识别的应用

深度神经网络(Deep Neural Networks, 简称DNN)是近年来机器学习领域中的研究热点,产生了广泛的应用.DNN具有深层结构.数千万参数需要学习,导致训练非常耗时.GPU有强大的计算能力,适合于加速深度神经网络训练.DNN的单机多GPU数据并行框架是腾讯深度学习平台的一部分,腾讯深度学习平台技术团队实现了数据并行技术加速DNN训练,提供公用算法简化实验过程.对微信语音识别应用,在模型收敛速度和模型性能上都取得了有效提升--相比单GPU 4.6倍加速比,数十亿样本的训练数天收敛,测

【深度学习系列2】Mariana DNN多GPU数据并行框架

[深度学习系列2]Mariana DNN多GPU数据并行框架 本文是腾讯深度学习系列文章的第二篇,聚焦于腾讯深度学习平台Mariana中深度神经网络DNN的多GPU数据并行框架. 深度神经网络(Deep Neural Networks, 简称DNN)是近年来机器学习领域中的研究热点[1][2],产生了广泛的应用.DNN具有深层结构.数千万参数需要学习,导致训练非常耗时.GPU有强大的计算能力,适合于加速深度神经网络训练.DNN的单机多GPU数据并行框架是Mariana的一部分,Mariana技术

python——对图像进行卷积操作,使用多个滤波器

线性滤波可以说是图像处理最基本的方法,它可以允许我们对图像进行处理,产生很多不同的效果.做法很简单.首先,我们有一个二维的滤波器矩阵(有个高大上的名字叫卷积核)和一个要处理的二维图像.然后,对于图像的每一个像素点,计算它的邻域像素和滤波器矩阵的对应元素的乘积,然后加起来,作为该像素位置的值.这样就完成了滤波过程. 对图像和滤波矩阵进行逐个元素相乘再求和的操作就相当于将一个二维的函数移动到另一个二维函数的所有位置,这个操作就叫卷积或者协相关.卷积和协相关的差别是,卷积需要先对滤波矩阵进行180的翻

卷积操作转化成矩阵乘法

参考:https://petewarden.com/2015/04/20/why-gemm-is-at-the-heart-of-deep-learning/ 平常都是无脑使用Pytorch提供的nn.Conv2d方法,但是并不关心具体该如何实现,原来是把卷积操作转化成矩阵乘法,而不是真的通过滑动卷积核来做卷积,下面做具体介绍. 首先看一下下面的示意图,左边是输入图像,右边是卷积核(为方便说明,只用了一个卷积核). 下面是用这个卷积核对输入图像做卷积操作,最后得到一个2维的平面 由下图可以看到卷

ICLR 2020 | 抛开卷积,multi-head self-attention能够表达任何卷积操作

近年来很多研究将nlp中的attention机制融入到视觉的研究中,得到很不错的结果,于是,论文侧重于从理论和实验去验证self-attention可以代替卷积网络独立进行类似卷积的操作,给self-attention在图像领域的应用奠定基础 论文: On the Relationship between Self-Attention and Convolutional Layers 论文地址:https://arxiv.org/abs/1911.03584 论文代码:https://githu

MariaDB 10之并行复制--延迟测试结果

测试参数: sysbench  --test=/root/sysbench0.5/sysbench/tests/db/insert.lua  --mysql-table-engine=innodb --oltp-table-size=1000000  --max-requests=0 --max-time=300 --num-threads=16  --oltp-tables-count=10 --report-interval=10  --mysql-host=10.8.8.100 --mys

opencv图像卷积操作

代码: #include <opencv2/opencv.hpp> #include <iostream> #include <math.h> using namespace cv; using namespace std; int main() { Mat src, dst, dst1; double t; //原图 src = imread(".//pic//test.jpg",IMREAD_UNCHANGED); if (src.empty()

matlab的二维卷积操作(转)

MATLAB的conv2函数实现步骤(conv2(A,B)): 其中,矩阵A和B的尺寸分别为ma*na即mb*nb ① 对矩阵A补零,第一行之前和最后一行之后都补mb-1行,第一列之前和最后一列之后都补nb-1列(注意conv2不支持其他的边界补充选项,函数内部对输入总是补零): ② 将卷积核绕其中心旋转180度: ③ 滑动旋转后的卷积核,将卷积核的中心位于图像矩阵的每一个元素,并求乘积和(即将旋转后的卷积核在A上进行滑动,然后对应位置相乘,最后相加):下面分别是shape=full, same