CUDA编程-(1)Tesla服务器Kepler架构和万年的HelloWorld
结合CUDA范例精解以及CUDA并行编程。由于正在学习CUDA,CUDA用的比较多,因此翻译一些个人认为重点的章节和句子,作为学习,程序将通过NVIDIA K40服务器得出结果。如果想通过本书进行CUDA编程,又不太懂CUDA和GPU的架构,可以将这个博客作为入门博客(但是希望你能有些基础,因为我介绍的并不是特别全面,只是捡了一些我困惑很久后来明白的知识点,如果完全不懂GPU的话,建议通读本书和介绍GPU的架构的书),我尽量在一个月更新完这本书的中文内容(部分)并补充一些自己的认识。欢迎大家评论和提问,转载请注明出处。
吐槽:书本有些地方英文过于书面化,真的不太容易让初学者理解。
正文
重点背景介绍:
Unlike previous generations that partitioned computing resources into vertex and pixel shaders, the CUDA Architecture included a unified shader pipeline, allowing each and every arithmetic logic unit (ALU) on the chip to be marshaled by a program intending to perform general-purpose computations. Because NVIDIA intended this new family of graphics processors to be used for general purpose computing, these ALUs were built to comply with IEEE requirements for single-precision floating-point arithmetic and were designed to use an instruction set tailored for general computation rather than specifically for graphics.
不同于之前将计算资源分配到顶点和像素着色器上(的架构),如今,CUDA架构包含了统一渲染总线,试图让每一个在芯片上的ALU算术逻辑单元都执行通用计算。因为NVIDIA公司(表示)这一新系列的图形处理器可用于通用计算,并且这些部件建立了符合IEEE单精度浮点运算的要求,因此为通用计算设计了一个指令集,且不是专门为了图形而设计的。
Furthermore, the execution units on the GPU were allowed arbitrary read and write access to memory as well as access to a software-managed cache known as shared memory. All of these features of the CUDA Architecture were added in order to create a GPU that would excel at computation in addition to performing well at traditional graphics tasks.
此外,在GPU上,执行单元可以任意读写访问的内存以及访问管理软件的缓存被称为共享内存。所有的这些CUDA架构的(设计)特点就是为了创造一个能擅长除了传统的图形计算的GPU(即,在通用计算等领域上也能够发挥更大的作用)。
第一章中,分别介绍了并行计算等背景、并行计算的重要性、GPU计算的产生崛起、早期的GPU计算以及CUDA在医学成像、计算流体动力学和环境科学领域的一些背景介绍,感兴趣可细读,不过个人感觉没什么用。关于安装CUDA网上教程多的是,不想重复赘述。不过提一点注意:你的电脑显卡必须是英伟达。
第二章主要是介绍安装的一些组件、需要的编译器gcc、g++等等,如果已经装好了,个人觉得也不需要看了。
第三章第一个例子
#include "../common/book.h" int main()
{
printf("hello world!\n");
return 0;
}
上面这个例子和你所写的所有的C代码一样,但是它却是一个CUDA程序,原因是,他是在host端执行的程序代码。这里我们引出了一个概念:host端和device端。device执行的CUDA的核函数,host端执行的是CPU上的执行代码。下图中可以看出如何写一个设备端的代码。
This program makes two notable additions to the original “Hello, World!”
example:
• An empty function named kernel() qualified with __global__
• A call to the empty function, embellished with <<<1,1>>>
上面那段程序和一开始的那个"hello world"相比主要有2个额外值得注意的地方。
• 一个不带参数的空 kernel()函数 和它的前缀 __global__ 关键字
• 通过<<<1,1>>> 和kernel函数建立联系
As we saw in the previous section, code is compiled by your system’s standard C compiler by default. For example, GNU gcc might compile your host code on Linux operating systems, while Microsoft Visual C compiles it on Windows systems. The NVIDIA tools simply feed this host compiler your code, and everything behaves as it would in a world without CUDA.
正如我们在前一节所看到的,代码是由您系统标准的编译器默认的。例如,GNU GCC可能在Linux操作系统下编译你的主机代码,而微软的Visual C是基于Windows系统下编译的。NVIDIA的工具只是提供(feed)你的代码给主机编译者(编译器),接下来的行为是没有任何CUDA的。
Now we see that CUDA C adds the __global__ qualifier to standard C. This mechanism alerts the compiler that a function should be compiled to run on a device instead of the host. In this simple example, nvcc gives the function kernel() to the compiler that handles device code, and it feeds main() to the host compiler as it did in the previous example. So, what is the mysterious call to kernel(), and why must we vandalize our standard C with angle brackets and a numeric tuple? Brace yourself, because this is where the magic happens.
现在我们看到,CUDA C加__global__关键字来限定标准C函数(类似于一种改写了该方法的意思)。该机制通知编译器函数应该编译运行在设备上而不是主机。在这个简单的例子中,NVCC给出了kernel()功能函数来处理设备代码,它提供main()函数到host端就像前面的例子中写的一样(大概意思就是kernel执行在设备端,其它代码执行在CPU上,原文是不是很拗口?!!)。所以,kernel()神秘的召唤是什么,以及我们为什么要破坏我们的标准C角括号和数字元组?振作起来,因为这是魔法发生的地方。
补充知识
GPU建立了一组SMX,多流处理器;每个SMX中,有许多的sp组成(流处理器),一个SMX的配置如下:
cores(都是SIMT cores(Single Instruction Multiple Threads) and 64k registers
GPU中的SIMT对应于CPU中的SIMD(Single Instruction Multiple Data)
64KB of shared memory / L1 cache
8KB cache for constants
48KB texture cache for read-only arrays
up to 2K threads per SMX
Tesla K40服务器架构基于 NVIDIA Kepler™ 架构的,如图下所示(官网Kepler架构说明,点击下载)
图中L2 Cache为2级缓存。K40一共15个SMX,每个SMX中之前已经说明,其中每个SMX核心数为192,得CUDA核心数为2880枚(15*192),内存大小12G。图下为各个参数:
SMX内的结构图如下。Warp是CUDA线程执行的最小单元,一个单元32个线程并行执行。寄存器文件大小:65536*32bit。 32个特殊功能单元 (SFU), 32个负载/存储单元(LD/ST),48k 只读数据一级数据缓存。64K共享内存或者128K,平台不同数据不同。Tex为纹理存储单元。
如今最新的K80服务器设置了双GPU,内存容量都翻倍了。感兴趣可以去了解。
1、程序写完后,以.cu结尾,切勿.cpp什么的。执行方式 $: nvcc test.cu -o test
2、如果理解了GPU底层架构将会更加清楚线程的执行方式(我不会对GPU的架构做过多的赘述,只介绍K40服务器的架构特点)如果感觉很迷糊说不清楚请参考这篇:显卡帝教你读懂GPU架构图 轻松做达人 以及下面官方的PDF
参考:
nv-ds-tesla-kcompute-arch-may-2012-cn
NVIDIA-Kepler-GK110-GK210-Architecture-Whitepaper
Tesla K80 An Inside Look Developer Whitepaper_CN
CUDA编程-(1)Tesla服务器Kepler架构和万年的HelloWorld的更多相关文章
- 【并行计算-CUDA开发】CUDA编程——GPU架构,由sp,sm,thread,block,grid,warp说起
掌握部分硬件知识,有助于程序员编写更好的CUDA程序,提升CUDA程序性能,本文目的是理清sp,sm,thread,block,grid,warp之间的关系.由于作者能力有限,难免有疏漏,恳请读者批评 ...
- [网络编程之客户端/服务器架构,互联网通信协议,TCP协议]
[网络编程之客户端/服务器架构,互联网通信协议,TCP协议] 引子 网络编程 客户端/服务器架构 互联网通信协议 互联网的本质就是一系列的网络协议 OSI七层协议 tcp/ip五层模型 客户端/服务器 ...
- CUDA编程
目录: 1.什么是CUDA 2.为什么要用到CUDA 3.CUDA环境搭建 4.第一个CUDA程序 5. CUDA编程 5.1. 基本概念 5.2. 线程层次结构 5.3. 存储器层次结构 5.4. ...
- CUDA编程之快速入门
CUDA(Compute Unified Device Architecture)的中文全称为计算统一设备架构.做图像视觉领域的同学多多少少都会接触到CUDA,毕竟要做性能速度优化,CUDA是个很重要 ...
- NVIDIA GPU架构与原理分析(一)——GPU简介与主流Fermi、Kepler架构GPU概述
1 GPU简介 图形处理单元GPU英文全称Graphic Processing Unit,GPU是相对于CPU的一个概念,NVIDIA公司在1999年发布GeForce256图形处理芯片时首先提出GP ...
- CUDA编程之快速入门【转】
https://www.cnblogs.com/skyfsm/p/9673960.html CUDA(Compute Unified Device Architecture)的中文全称为计算统一设备架 ...
- Socket服务器整体架构概述
转载:http://www.cnblogs.com/tianzhiliang/archive/2010/10/28/1863684.html Socket服务器主要用于提供高效.稳定的数据处理.消息转 ...
- CUDA编程(六)进一步并行
CUDA编程(六) 进一步并行 在之前我们使用Thread完毕了简单的并行加速,尽管我们的程序运行速度有了50甚至上百倍的提升,可是依据内存带宽来评估的话我们的程序还远远不够.在上一篇博客中给大家介绍 ...
- CUDA编程模型
1. 典型的CUDA编程包括五个步骤: 分配GPU内存 从CPU内存中拷贝数据到GPU内存中 调用CUDA内核函数来完成指定的任务 将数据从GPU内存中拷贝回CPU内存中 释放GPU内存 *2. 数据 ...
随机推荐
- bzoj1901:Zju2112 Dynamic Rankings
思路:树套树,我写了两种,一种是线段树套splay,线段树维护区间信息,splay维护第k大,一种是树状数组套权值线段树(并不是什么可持久化线段树,只不过是动态开点罢了,为什么网上一大堆题解都是可持久 ...
- C++里容易忽视却不能忽视的
1 define 只是简单地文本替换. 2 每个机器的字长不同. 3 每个类型在不同的机器上,所占用的内存空间不同. 4 每个机器内部的字节大小端不同. 5 并不是所有的编译器或机器都支持最新的C++ ...
- ASP.NET中的母版页
添加一个"母版页",使用<asp:ContentPlaceHolder>挖坑,新建的母版页已经自动设置了两个ContentPlaceHolder创建使用母版页的具体页面 ...
- Eclipse相关
JDK版本更换相关: 启动eclipse会报错:根据报错信息后面提示的eclipse配置信息,我将配置中的c:/xx/javaw.exe给移除了.并在eclipse.ini中配置了-vm d:/Jav ...
- python 自动化之路 day 08_2 网络编程
本节内容 Socket介绍 Socket参数介绍 基本Socket实例 Socket实现多连接处理 通过Socket实现简单SSH 通过Socket实现文件传送 作业:开发一个支持多用户在线的FTP程 ...
- erlang 里的if 和 case
case Expression of Pattern1 [when Guard1] -> Expr_seq1; Pattern2 [when Guard2] -> Expr_seq2; … ...
- CentOS6.5下docker的安装及遇到的问题和简单使用
Docker是一个开源的应用容器引擎,可以轻松的为任何应用创建一个轻量级的.可移植的.自给自足的容器.利用Linux的LXC.AUFS.Go语言.cgroup实现了资源的独立,可以很轻松的实现文件.资 ...
- POJ 3264 Balanced Lineup 简单RMQ
题目:http://poj.org/problem?id=3264 给定一段区间,求其中最大值与最小值的差. #include <stdio.h> #include <algorit ...
- RSA算法原理及实现
参考资料: 阮哥的日志:http://www.ruanyifeng.com/blog/2013/06/rsa_algorithm_part_one.html http://www.ruanyifeng ...
- ios开发之C语言第4天
自增和自减运算 自增运算符 ++ 自增表达式 1>.前自增表达式. int num = 1; ++num; 2>.后自增表达式 int num = 1; n ...