cuda编程_CUDA编程入门(四)并行归约算法

这一篇我们一起学习一下如何使用CUDA实现并行归约算法。

首先我们要知道什么是并行归约。并行归约(Reduction)是一种很基础的并行算法,简单来说,我们有N个输入数据,使用一个符合结合律的二元操作符作用其上,最终生成1个结果。这个二元操作符可以是求和、取最大、取最小、平方、逻辑与或等等。

我们以求和为例,假设输入如下:

int array[8] =  [3, 1, 7, 0, 4, 1, 6, 3]

在串行的情况下,算法很容易实现,一般我们会使用下面这样的代码。

int 

但当我们试图进行并行计算时,问题就会变得复杂。

由于加法的交换律和结合律,数组可以以任意顺序求和。所以我们会自然而然产生这样的思路:首先把输入数组划分为更小的数据块,之后用一个线程计算一个数据块的部分和,最后把所有部分和再求和得出最终结果。

依照以上的思路,我们可以按下图这样计算。就上面的输入例子而言,首先需要我们开辟一个8个int的存储空间,图中一行的数据代表我们开辟的存储空间。计算时首先将相邻的两数相加(也称相邻配对),结果写入第一个数的存储空间内。第二轮迭代时我们再将第一次的结果两两相加得出下一级结果,一直重复这个过程最后直到我们得到最终的结果,空白方框里面存储的内容是我们不需要的。这个过程相当于,每一轮迭代后,选取被加数的跨度翻倍,后面我们核函数就是这样实现的。

8dee194ba4332e1ffca2f62e12fb6369.png
相邻配对实现并行归约

相比与串行计算,我们只用了3轮迭代就得出了8个数的和,时间复杂度由O(N)变为O(logN)

当然使用归约算法时我们不会只有这么小的输入数组,这时候就要用到线程块了,我们可以把输入数组先划分成很多包含8个int型值的数组,每一个小数组分配给一个线程块,最后再将所有的结果传回主机串行求和。

主函数如下,与我们上一个例程结构类似,先初始化,分配内存,然后运行核函数,最后和CPU对照组对比,检验结果是否正确。我们重点关注分配线程网格和线程块的主干部分。与上面例子里讲的8元素数组不同,实际使用时为了达到高加速比,我们会把输入数组分成更大的块。

这里我们使用一个16M(16777216)大小的输入数组,分成的小数组大小为1K(1024)。所以程序里将block设置为(1024, 1)的大小,每个线程块完成一个小数组的求和。一共需要16K(16384)个线程块,所以我们设置grid为(16384, 1)。每个线程块的求和结果都保存在全局内存里,等所有线程完成后,统一传回主机,在主机里串行求和得到最后的结果。注意这里的block和grid设置并不是最优,只是为了简单,下一篇中我们会进行优化。

int 

核函数具体编程实现如下。我们利用一个stride变量,实现不同轮数时被加数的选择。每当计算一轮后,选取被加数的跨度会乘2。在这里,有心的同学就会发现了,第一轮计算中,其实只有一半的线程是活跃的,而且每进行一轮计算后,活跃的线程数都会减少一半,这是条件表达式的使用造成的。比如在第一轮迭代时,只有偶数ID的线程会为True,其主体才能得到执行。这会导致线程束的分化,也就是说只有一部分线程是活跃的,但是所有的线程仍然都会被调度,因为硬件调度线程是以线程束(连续32个线程)为单位进行调度的。这肯定会影响我们程序的执行效率,不过不用太担心,我们下一篇就会提出解决这个问题的方法。

__global__ 

最后我们看看运行结果,cpu花费89.3ms,而gpu花费2.5ms,运算结果一致。

a3e3e2ec1b8d1f1b32572b5455226ac9.png
终端截图

完整代码和编译生成的可执行文件放在这里:

https://github.com/ZihaoZhao/CUDA_study/tree/master/Reduction

总结一下,这一篇我们使用CUDA完成了一个基础的并行归约算法,不过这算法还有很大的优化空间,接下来我们一起对这个算法进行优化,看看能再加快多少。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/262256.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在ubuntu下各种格式软件安装及常用命令

Ubuntu下软件安装的几种方式: (1).bundle 格式 以VMware-Workstation-Full-7.0.0-203739.i386.bundle为例 命令如下:sudo sh VMware-Workstation-7.0.0-203739.i386.bundle(先切换到该文件所在文件夹) (2).deb格式 最常用的是deb包,deb是deb…

解决Windows客户端访问vsftpd服务器中文乱码问题

上周五-业务部同事反馈客户使用我司的FTP服务,发现文件和目录是中文全部乱码,不方便查看修改文件目录等操作故障原因:vsftpd不能处理字符编码的转换,Windows使用GBK编码,linux使用zh_CN.UTF-8编码解决方法:1、使用能够…

csgo怎么控制电脑玩家_电脑怎么远程控制他人电脑,教您给电脑设置远程控制的方法...

有些时电脑出现了一些我们解决不了的问题时,这时我们一定第一时间想到就是让电脑高手帮忙看一下问题;但要对方在异地该办呢,那就通过电脑远程来解决了;那么问题又来了,电脑怎么远程控制他人电脑呢?小编下面…

JAVA实验报告九异常处理_JAVA实验报告_Java异常处理

贵州大学实验报告学院:计信学院专业:网络工程班级:101 姓名学号实验组实验时间05.27 指导教师肖源源成绩实验项目名称Java异常处理实验目的1)掌握Java异常的概念及工作机制2)掌握异常的分类3)掌握抛出异常语句的使用(throw)4)掌握抛出捕获处理…

win8下vs2012加wp8 sdk开发xna4.0PC游戏

vs2012安装wp8后,只能开发手机端的xna游戏程序,没有xbox和pc端的,看来官方是不打算更新了,不过我们还是有办法的。前提条件下,您得安装了vs2010和xna4.0 game studio或者是windows phone sdk 7.1。如果您没有安装wp8&a…

div悬浮在固定位置_悬浮式超声波致动器概要及研究动向

作者:东京工业大学 中村 健太郎1. 序言以往的超声波马达是通过摩擦力驱动,固定片压电振子与转子接触,通过振动摩擦转子从而获得旋转力和推动力。虽然具有高转矩、高控制性等特点,从原理上讲其速度无法超过振子振动速度。压电振子的…

基于Java的设计开题报告_基于Java的电子邮件的收发系统的设计与实现开题报告...

基于Java的电子邮件的收发系统的设计与实现开题报告 (8页)本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦!9.90 积分开题报告 基于 Java 的电子邮件的收发系统的设计与实现 一、选题的背景、意义 1、 电…

Java GUI 开发专题

Java GUI 开发专题 IBM http://www.ibm.com/developerworks/cn/java/j-gui/#N10095 作者:wenhai_zhang 发表于2009-11-25 23:53:00 原文链接 阅读:7 评论:0 查看评论 转载于:https://www.cnblogs.com/wenhaizhang/archive/2009/11/25/2099172…

Zookeeper-源码启动

源码启动zookeeper zookeeper源码下载地址: //选择分支3.5.8 https://github.com/apache/zookeeper.git 源码导入idea后,org.apache.zookeeper.Version类会报错,需要建一个辅助类 //全局搜索org.apache.zookeeper.Version这个类就找到了…

python之获取微信服务器的ip地址

# -*- coding: cp936 -*- #PYTHON 27 #xiaodeng #获取微信服务器的ip地址import urllib urlhttps://api.weixin.qq.com/cgi-bin/getcallbackip data{access_token:VchuOKNr8X9tZVDrY_yG9qiJus_1nO1a7uT_iwWVwgGFdzPhPyaqreTE_qMKPas4SwRNif5k0A1zVw6Y9eTPI4CAYiUwpJvHdBt4fzDTR…

pandas 取excel 中的某一列_Excel快速分表(xlwings+pandas)

Excel总表快速分表:step1: 读取exel数据到DataFramestep2: dataframe中数据进行筛选step3:将筛选完的数据存储到excel中工作中应用实例step1:读取Excel的数据到pandas 的Dataframe方法1:采用pandas,读取sheet1的内容到…

[转]C#连接操作mysql实例

本文转自:http://hi.baidu.com/zhqngweng/item/c4d2520cb7216877bfe97edf 第三方组件:Mysql.Data.dll说明:去官方网站下载Mysql.Data.dll,然后在项目中添加该组件的引用,在代码页里输入using Mysql.Data.MysqlClient&a…

通过点击切换文本框内容的脚本示例

定义一个字符串为内容的数组,每一行的多个文本框为一组,要求点击切换内容,且内容不重复. 代码 1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">2 <html>3 <head>4 <title>New Document </title>5 <script>6 …

qmenu只在鼠标单击时消失_两种方法解决win10电脑无法使用无线鼠标问题

使用有线鼠标时用户们是否也都会被那条线控制住&#xff0c;有时需要大范围移动时并不行&#xff0c;现在很多用户都会选择使用无线鼠标&#xff0c;因为可以随意移动使用更加方便。但是在使用中也有用户遇到了麻烦&#xff0c;使用win10连接鼠标后无法使用&#xff0c;这是要怎…

蓝桥杯 带分数

来一个全排列&#xff0c;然后枚举跟/的位置&#xff0c;时间复杂度大概是&#xff0c;9。*28历届试题 带分数 时间限制&#xff1a;1.0s 内存限制&#xff1a;256.0MB问题描写叙述100 能够表示为带分数的形式&#xff1a;100 3 69258 / 714。 还能够表示为&#xff1a;10…

java tempfile read_Java 文件操作

Java 实例 - 文件写入以下实例演示了使用 write() 方法向文件写入内容&#xff1a;import java.io.*;public class WriteDemo {public static void main(String[] args) {try {BufferedWriter out new BufferedWriter(new FileWriter("runoob.txt"));out.write(&quo…

设置图片圆角 或者圆形

1.//用画图的方式设置圆角 mImageView.image[UIImage imageNamed:"bg1.png"]; mImageView.frameCGRectMake(center.x-radius, center.y-radius, 2*radius, 2*radius); mImageView.layer.cornerRadiusradius;//设置圆角半径 mImageView.layer.masksToBoundsYES; [mIma…

“Word.Tables”并不包含“Item”的定义的解决办法

C#调用WORD时出错如下&#xff1a; object missingValue Type.Missing;object location strInfo.Length; //如果location超过已有字符的长度将会出错。一定要比"明细表"串多一个字符 Word.Range rng2 wordDoc.Range(ref location,…

线程的几个状态

Runnable&#xff1a;一般指该线程正在执行状态中&#xff0c;该线程占用了资源&#xff0c;正在处理某个请求&#xff0c;例如有可能在对某个文件操作&#xff0c;有可能进行数据类型等转换。Waiting on condition&#xff1a;等待资源&#xff0c;或等待某个条件的发生。具体…

c++ 数组的输入遇到特定字符停止输入_滑动窗口思维--挑战“无重复字符的最长子串”

文章来源&#xff1a; 饭饭的Python学习之路作者&#xff1a; 一粒米饭今天要挑战的是“无重复字符的最长子串”。难度&#xff1a;中等题目描述&#xff1a;给定一个字符串&#xff0c;请你找出其中不含有重复字符的 最长子串 的长度。示例1:输入: "abcabcbb"输出: …