CUDA显卡运算编程菜鸟入门指南1——Hello world - yfszzx的专栏 - 博客频道 - CSDN.NET
第一次知道有显卡(GPU)编程这个东西,是去年比特币最热门的时候,看了几篇关于比特币的文章,说比特币挖矿要靠显卡,CPU的速度与GPU根本就没法比,于是就非常好奇,显卡是什么神奇的东西?为什么运算速度会比CPU快很多?当时也只是好奇而已,根本没想过这东西会与自己有任何关系。
去年年底的时候,我开始研究机器学习,试着用PHP编了几个遗传算法和神经网络算法的程序,发现很有趣,功能很强大,我一直想做医学方面的人工智能开发,觉得机器学习这个东西很有用,但就是运算速度太慢,估算了一下按程序的运行速度,要初略的解决我的问题至少要算一两个星期,如果要以较高的精确度解决我的问题,可能要算几个月。仔细权衡利弊之后,我决定从头学C语言,毕竟C是高级语言中运算速度最快的(现在后悔,当时要从C++开始学就更好了)。从初学到把我的php程序改写为C,一共花了两个星期左右,可喜的是运算速度提高了大约150倍。
后来发现神经网络用遗传算法来驱动远不如用退火算法驱动效率高,并且神经网络算法可以有很多冗余计算可以去掉,这样一来,我的算法效率前前后后又提高了一万多倍,与最初的PHP程序相比,运算效率已经提高了大约200万倍。 尽管如此,我还是不满意,因为问题稍微复杂些,且要求的精度再高些,我的电脑还是要没日没夜转好几天,我希望程序运算速度能够再有至少一个数量级的提升,在软件上能改进的地方几乎都改进了,只能在硬件上想办法了。
我本以为,按照摩尔定律,CPU的运算速度每一年半要提升一倍,不怕大家笑话,我现在的电脑是2007年买的,已经过去七年了,最新的CPU速度应该提升二十多倍了,于是我上网查了一下,竟然发现最新款的电脑,CPU的主频不过比我的多10%左右,这是怎么回事?再查才知道,原来CPU的摩尔定律到2008年左右就失效了,这么多年来CPU主频都没有大的变化,主要靠不断增加CPU的数量(双核、四核、八核.......)进一步提高电脑性能,但这种多核结构对于我要解决的问题,帮助似乎并不明显。
于是我就想到比特币文章中提到的GPU运算——这个从来没觉得会与自己有关系的东西。
查了一些文章,大致了解到GPU之所以比CPU快得多,并不是GPU的处理器运算速度更快——其实目前最好的显卡,处理器的主频也不到CPU的一半——但是CPU只有一个处理器,而GPU的处理器少则几十个,多则几千个,一只手干活干得再快,也没有成百上千只手一起干活干得快,就是这个道理。
GPU这个特点决定了并不是所有程序都适合用GPU来加速,只有你的问题能够分解为若干能够独立执行的部分(即一部分程序的运算,并不依赖于另一部分运算的运行结果),才适合考虑用GPU来处理,这也是GPU编程的核心观念:并行运算。
既然GPU是成百上千只手一起干活,那么GPU的价格为什么不是CPU的成百上千倍呢?关键就在于GPU的“手”与CPU的“手”相比是带有明显残疾的,只有完成某些特定动作的时候效率高,完成其他动作效率就很低。具体表现在:
(1)所有的“手”(或者叫处理器、线程)完成相同动作时效率高,完成不同动作时效率低——这一条是显卡编程最关键、最核心的部分,这决定了GPU虽然有几千只手,但不可能像工厂工人那样进行流水作业,你装填,我打包,他装箱,这对于GPU是行不通的。大家都一起打包,然后大家一起来装箱,只有这样的方式才适合让GPU来处理。
(2)如果各个并行的部分(即各个线程),需要共享大量数据,那么不适合用GPU进行处理。要注意,我说的是“不能共享大量数据”,这里并不是说GPU不适合处理大量数据,相反,由于GPU具有较大的显存空间(比较差的显卡也有2G显存)和非常快的数据吞吐速度(专业术语叫带宽),所以非常适合做大数据的处理。GPU编程的一个早期经典案例就是医学图像的处理,据说有个医生发明了一种彩超快速诊断子宫肌瘤的方法,但是如果用CPU处理几个T的彩超检查数据的话,几天都搞不定,后来改用GPU处理,几十分钟就解决了——所以处理大数据是GPU的强项。
但这是指各个线程独立的读取一部分专属于自己的数据,那么处理的速度可以很高。如果大量的线程,要相互交错的同时访问大量数据那么运行效率就很低。打个比方:菜市场每一个摊位相当于一个要被访问的数据,逛菜市场的人相当于不同的线程,那么大家杂乱无章的在市场里乱逛,运行效率就很低。如果大家排好队进场,规定一个人只准面对一个摊位,那么运行效率就会很高。
(3)并行处理的线程数不能太少。如果你的程序只能分解为几百个并行运算的部分,就不适合用GPU来处理——至少要有几千个并行的线程才能勉强体现出GPU的优势,如果你的程序撑死了也就分解为两三千个并行的部分,那么还是建议你不要考虑用GPU加速了——举个例子,我用GPU运行我的神经网络(我的显卡非常差,只有48个处理器),刚把程序运行通的时候,我安排了1024个线程进行测试,与我原来的CPU程序相比,速度只提高了20%左右,让我大失所望。后来发发狠,把并行的线程数安排到8192个——速度竟然提高到了原来的八倍左右——这让我欣喜若狂,这意味着如果我换更好的显卡,比如有两千多个处理器的显卡,那么我的程序速度还有四五十倍的提升空间,这样一来我的算法速度有望比在CPU的速度提高2-3个数量级,想想都让人兴奋。
需要说明一下,这个教程叫“菜鸟入门”,这里的“菜鸟”是指显卡编程方面的菜鸟,而不是指编程菜鸟。要学显卡编程,一定要对C/C++比较熟练,对指针的运用比较自如,才可能进行显卡编程——也可以说距离显卡编程就很近了,据说很久很久以前......显卡编程是一件非常麻烦的大工程,后来一种叫CUDA的东西横空出世——显卡厂商NVIDIA推出的显卡运算平台——显卡编程就变得非常简单了,只要在熟练C的前提下,学几个简单的语句就可以搞定。
由于我是在windows上进行显卡编程的,我简单说一下我我在windows上安装CUDA遇到的一些问题(详细安装步骤请自行搜索相关文献,我这里只提一下文献中很少提及的需要注意的问题,以帮助各位少走弯路,至于使用Linux的同学,只能是自己查阅文献慢慢摸索了)。
(一)需要先安装Visual Studio(其他C/C++的SDK似乎都不行),有的文献说可以用VC EXPRESS,但我安了VC EXPRESS,死活用不了,后来装了全套Visual Studio 才搞定。
(二)安装好Visual Studio之后,到NVIDIA官网下载CUDA安装包,安装时务必选择“自定义安装”,务必勾选全部安装项目。
(三)CUDA安装好后,可以搜索一个叫CUDA-Z的小软件,这个软件可以显示你的显卡的状态。下载运行后,如果告诉你显卡没有运行,很可能是你的显卡驱动太旧了——哪怕你是刚下载的最新的安装包,也可能出这个问题——你需要升级显卡驱动。另外我有个朋友遇到这样的问题:显卡没有运行,后来发现他是远程登陆,他到本地使用的时候,显卡就正常了——我分析是远程登陆后,显卡就休眠了。
上面步骤完成后,就可以打开VS,新建一个CUDA工程,然后就可以开始第一个CUDA程序了:
- #include <cuda_runtime.h>
- void main()
- {printf("Hello world");
- }
http://blog.csdn.net/yfszzx/article/details/41654415
慢着,这个程序和C有什么区别?用到显卡了吗?
答:没有区别,没用显卡。如果你非要用显卡干点什么事情的话,可以改成这个样子:
- #include <cuda_runtime.h>
- __global__ void test()
- {int i=0;}
- void main()
- {test<<<1,1>>>();
- printf("Hello world");
- }
这样,我们就用显卡的一个线程,执行了一个int i=0语句。
CUDA显卡运算编程菜鸟入门指南1——Hello world - yfszzx的专栏 - 博客频道 - CSDN.NET的更多相关文章
- CUDA从入门到精通 - Augusdi的专栏 - 博客频道 - CSDN.NET
http://blog.csdn.net/augusdi/article/details/12833235 CUDA从入门到精通 - Augusdi的专栏 - 博客频道 - CSDN.NET CUDA ...
- Cocos Creator - 入门教程项目 - 博客频道 - CSDN.NET
3457 教程司令部 [20160418] | Cocos Creator - CocoaChina CocoaChina_让移动开发更简单cocoachina.com 2033 Cocos Crea ...
- C++ STL中Map的相关排序操作:按Key排序和按Value排序 - 编程小径 - 博客频道 - CSDN.NET
C++ STL中Map的相关排序操作:按Key排序和按Value排序 - 编程小径 - 博客频道 - CSDN.NET C++ STL中Map的相关排序操作:按Key排序和按Value排序 分类: C ...
- 基于libevent, libuv和android Looper不断演进socket编程 - 走向架构师之路 - 博客频道 - CSDN.NET
基于libevent, libuv和android Looper不断演进socket编程 - 走向架构师之路 - 博客频道 - CSDN.NET 基于libevent, libuv和android L ...
- 搞IT,算法编程不错的学习网址 & 一些专栏博客大神的地址(汇总)
博客专栏大神 王晓华(算法的乐趣) 算法系列:http://blog.csdn.net/orbit/article/category/830251 PostgreSQL深入理解内核系列:http:// ...
- Ruby菜鸟入门指南
写这篇文章的初衷源于我的伙伴们在上手Ruby过程中,表现实在是太让人拙计了.由于项目的急功近利,需要迅速入门Ruby并上手项目.所以很多开发者在实际开发过程中,不熟悉Ruby的表达方式,也会沿用其他语 ...
- 【Go 入门学习】第一篇关于 Go 的博客--Go 爬虫初体验
一.写在前面 其实早就该写这一篇博客了,为什么一直没有写呢?还不是因为忙不过来(实际上只是因为太懒了).不过好了,现在终于要开始写这一篇博客了.在看这篇博客之前,可能需要你对 Go 这门语言有些基本的 ...
- GitHub入门(一)GIT配置与Hexo博客搭建
首先安装配置Git环境,由于本人使用Windows操作系统所以从msysgit.github.io下载msysGit Windows版本,安装.(Mac一般自带Git) 安装的时候一般使用默认选项,其 ...
- php小白和菜鸟 上班路上可以看的修行博客
上班地铁 公交上我们不要去追剧 不要去打游戏 不要看看有效性的海量新闻, 我们需要去技术博客里遨游, 下面就推荐点与php有关的可以学习的技术博客; 大部分程序员在自学的道路上不知道走了多少坑,这个视 ...
随机推荐
- mvn deploy命令上传包
需求:有的时候需要单独上传release jar包,因为存在工程代码在A内网SVN,Nexus在B内网.这种情况下使用VPN也无法解决Jar包发布的问题. 这个时候采取的方式只能是: 打出jar包 - ...
- CentOS上传下载查看命令
之前往CentOS中上传都用ftp软件,这里介绍一种另外的上传下载方式,两个命令轻松搞定.这两个命令目前只针对Xshell和SecureCRT等远程终端软件才支持,并且还会有时间的限制.大概30秒不上 ...
- 【CF932G】Palindrome Partition 回文自动机
[CF932G]Palindrome Partition 题意:给你一个字符串s,问你有多少种方式,可以将s分割成k个子串,设k个子串是$x_1x_2...x_k$,满足$x_1=x_k,x_2=x_ ...
- 【CF840C】On the Bench DP
[CF840C]On the Bench 题意:给你一个长度为n的数组{ai},定义一个1到n的排列是合法的,当且仅当对于$1\le i <n$,$a_i\times a_{i+1}$不是完全平 ...
- 画面渲染:实时渲染(Real-time Rendering)、离线渲染(Offline Rendering)[转]
实时渲染(Real-time Rendering) 实时渲染的本质就是图形数据的实时计算和输出.最典型的图形数据源是顶点.顶点包括了位置.法向.颜色.纹理坐标.顶点的权重等.在第一代渲染技术中(198 ...
- NodeJS 实现基于 token 的认证应用
此段摘自 http://zhuanlan.zhihu.com/FrontendMagazine/19920223 英文原文 http://code.tutsplus.com/tutorials/tok ...
- docker swarn集群笔记
.安装Docker 三剑客: curl -L https://github.com/docker/machine/releases/download/v0.10.0/docker-machine-`u ...
- 如何使QLineEdit禁止编辑
在写程序的时候喜欢使用QLineEdit,用来显示打开文件的路径.但是很不喜欢被编辑.那么要怎么设置不可编辑呢. (1)调用lineEdit->setEnabled(False) #不可编辑了 ...
- thinkphp实现采集功能的三种方法!
最近在做一些数据分析,由于上网找数据比较麻烦,所以写了一个采集网站数据的方法.具体方法如下: 方法一:QueryList 个人感觉比较好用,采集详情比较不错的选择,但是采集复杂一点的列表,不好用.具体 ...
- 从底层源码浅析Mybatis的SqlSessionFactory初始化过程
目录 搭建源码环境 POM依赖 测试SQL Mybatis全局配置文件 UserMapper接口 UserMapper配置 User实体 Main方法 快速进入Debug跟踪 源码分析准备 源码分析 ...