GPU CUDA 经典入门指南

转自:http://luofl1992.is-programmer.com/posts/38830.html

CUDA编程中,习惯称CPU为Host,GPU为Device。编程中最开始接触的东西恐怕是并行架构,诸如Grid、Block的区别会让人一头雾水,我所看的书上所讲述的内容比较抽象,对这些概念的内容没有细讲,于是在这里作一个整理。

Grid、Block和Thread的关系

Thread  :并行运算的基本单位(轻量级的线程)
Block   :由相互合作的一组线程组成。一个block中的thread可以彼此同步,快速交换数据,最多可以同时512个线程。
Grid     :一组Block,有共享全局内存
Kernel :在GPU上执行的程序,一个Kernel对应一个Grid。

其结构如下图所示:

 1 /*
 2 另外:Block和Thread都有各自的ID,记作blockIdx(1D,2D),threadIdx(1D,2D,3D)
 3 Block和Thread还有Dim,即blockDim与threadDim. 他们都有三个分量x,y,z
 4 线程同步:void __syncthreads(); 可以同步一个Block内的所有线程
 5 总结来说,每个 thread 都有自己的一份 register 和 local memory 的空间。
 6 一组thread构成一个 block,这些 thread 则共享有一份shared memory。
 7 此外,所有的 thread(包括不同 block 的 thread)都共享一份
 8 global memory、constant memory、和 texture memory。
 9 不同的 grid 则有各自的 global memory、constant memory 和 texture memory。
10 */

 

存储层次
1
per-thread register 1 cycle 2 per-thread local memory slow 3 per-block shared memory 1 cycle 4 per-grid global memory 500 cycle,not cached!! 5 constant and texture memories 500 cycle, but cached and read-only 6 分配内存:cudaMalloc,cudaFree,它们分配的是global memory 7 Hose-Device数据交换:cudaMemcpy
变量类型
1
__device__ // GPU的global memory空间,grid中所有线程可访问 2 __constant__ // GPU的constant memory空间,grid中所有线程可访问 3 __shared__ // GPU上的thread block空间,block中所有线程可访问 4 local // 位于SM内,仅本thread可访问 5 // 在编程中,可以在变量名前面加上这些前缀以区分。
数据类型
1
// 内建矢量类型: 2 int1,int2,int3,int4,float1,float2, float3,float4 ... 3 // 纹理类型: 4 texture<Type, Dim, ReadMode>texRef; 5 // 内建dim3类型:定义grid和block的组织方法。例如: 6 dim3 dimGrid(2, 2); 7 dim3 dimBlock(4, 2, 2); 8 // CUDA函数CPU端调用方法 9 kernelFoo<<<dimGrid, dimBlock>>>(argument);
函数定义
1
__device__ // 执行于Device,仅能从Device调用。限制,不能用&取地址;不支持递归;不支持static variable;不支持可变长度参数 2 __global__ // void: 执行于Device,仅能从Host调用。此类函数必须返回void 3 __host__ // 执行于Host,仅能从Host调用,是函数的默认类型 4 // 在执行kernel函数时,必须提供execution configuration,即<<<....>>>的部分。 5 // 例如: 6 __global__ void KernelFunc(...); 7 dim3 DimGrid(100, 50); // 5000 thread blocks 8 dim3 DimBlock(4, 8, 8); // 256 threads per block 9 size_t SharedMemBytes = 64; // 64 bytes of shared memory 10 KernelFunc<<< DimGrid, DimBlock, SharedMemBytes >>>(...);

 

数学函数
1
CUDA包含一些数学函数,如sin,pow等。每一个函数包含有两个版本, 2 例如正弦函数sin,一个普通版本sin,另一个不精确但速度极快的__sin版本。
内置变量
1
/* 2 gridDim, blockIdx, blockDim, 3 threadIdx, wrapsize. 4 这些内置变量不允许赋值的 5 */
编写程序
1
/* 2 目前CUDA仅能良好的支持C,在编写含有CUDA代码的程序时, 3 首先要导入头文件cuda_runtime_api.h。文件名后缀为.cu,使用nvcc编译器编译。 4 目前最新的CUDA版本为5.0,可以在官方网站下载最新的工具包,网址为: 5 https://developer.nvidia.com/cuda-downloads 6 该工具包内包含了ToolKit、样例等,安装起来比原先的版本也方便了很多。 7 */
 相关扩展
1
1 GPU硬件 2 // i GPU一个最小单元称为Streaming Processor(SP),全流水线单事件无序微处理器, 3 包含两个ALU和一个FPU,多组寄存器文件(register file,很多寄存器的组合), 4 这个SP没有cache。事实上,现代GPU就是一组SP的array,即SPA。 5 每一个SP执行一个thread 6 7 // ii 多个SP组成Streaming Multiprocessor(SM)。 8 每一个SM执行一个block。每个SM包含8个SP; 9 2个special function unit(SFU): 10 这里面有4个FPU可以进行超越函数和插值计算 11 MultiThreading Issue Unit:分发线程指令 12 具有指令和常量缓存。 13 包含shared memory 14 15 // iii Texture Processor Cluster(TPC) :包含某些其他单元的一组SM 16 17 2 Single-Program Multiple-Data (SPMD)模型 18 19 // i CPU以顺序结构执行代码, 20 GPU以threads blocks组织并发执行的代码,即无数个threads同时执行 21 22 // ii 回顾一下CUDA的概念: 23 一个kernel程序执行在一个grid of threads blocks之中 24 一个threads block是一批相互合作的threads: 25 可以用过__syncthreads同步; 26 通过shared memory共享变量,不同block的不能同步。 27 28 // iii Threads block声明: 29 可以包含有1到512个并发线程,具有唯一的blockID,可以是1,2,3D 30 同一个block中的线程执行同一个程序,不同的操作数,可以同步,每个线程具有唯一的ID 31 32 3 线程硬件原理 33 34 // i GPU通过Global block scheduler来调度block, 35 根据硬件架构分配block到某一个SM。 36 每个SM最多分配8个block,每个SM最多可接受768个thread 37 (可以是一个block包含512个thread, 38 也可以是3个block每个包含256个thread(3*256=768!))。 39 同一个SM上面的block的尺寸必须相同。每个线程的调度与ID由该SM管理。 40 41 // ii SM满负载工作效率最高!考虑某个Block,其尺寸可以为8*8,16*16,32*32 42 8*8:每个block有64个线程, 43 由于每个SM最多处理768个线程,因此需要768/64=12个block。 44 但是由于SM最多8个block,因此一个SM实际执行的线程为8*64=512个线程。 45 16*16:每个block有256个线程,SM可以同时接受三个block,3*256=768,满负载 46 32*32:每个block有1024个线程,SM无法处理! 47 48 // iii Block是独立执行的,每个Block内的threads是可协同的。 49 50 // iv 每个线程由SM中的一个SP执行。 51 当然,由于SM中仅有8个SP,768个线程是以warp为单位执行的, 52 每个warp包含32个线程,这是基于线程指令的流水线特性完成的。 53 Warp是SM基本调度单位,实际上,一个Warp是一个32路SIMD指令 54 。基本单位是half-warp。 55 如,SM满负载工作有768个线程,则共有768/32=24个warp 56 ,每一瞬时,只有一组warp在SM中执行。 57 Warp全部线程是执行同一个指令, 58 每个指令需要4个clock cycle,通过复杂的机制执行。 59 60 // v 一个thread的一生: 61 Grid在GPU上启动; 62 block被分配到SM上; 63 SM把线程组织为warp; 64 SM调度执行warp; 65 执行结束后释放资源; 66 block继续被分配.... 67 68 4 线程存储模型 69 70 // i Register and local memory:线程私有,对程序员透明。 71 每个SM中有8192个register,分配给某些block, 72 block内部的thread只能使用分配的寄存器。 73 线程数多,每个线程使用的寄存器就少了。 74 75 // ii shared memory:block内共享,动态分配。 76 如__shared__ float region[N]。 77 shared memory 存储器是被划分为16个小单元, 78 与half-warp长度相同,称为bank,每个bank可以提供自己的地址服务。 79 连续的32位word映射到连续的bank。 80 对同一bank的同时访问称为bank conflict。 81 尽量减少这种情形。 82 83 // iii Global memory:没有缓存!容易称为性能瓶颈,是优化的关键! 84 一个half-warp里面的16个线程对global memory的访问可以被coalesce成整块内存的访问,如果: 85 数据长度为4,8或16bytes;地址连续;起始地址对齐;第N个线程访问第N个数据。 86 Coalesce可以大大提升性能。 87 88 // uncoalesced 89 Coalesced方法:如果所有线程读取同一地址, 90 不妨使用constant memory; 91 如果为不规则读取可以使用texture内存 92 如果使用了某种结构体,其大小不是4 8 16的倍数, 93 可以通过__align(X)强制对齐,X=4 8 16

 

 example://想象为二维数组

int row = blockIdx.y * blockDim.y + threadIdx.y; //thread 所在的行

int col = blockIdx.x * blockDim.x + threadIdx.x; //thread 所在的列

blockDim是指每个block的size,blockDim.y 相当于block的height,blockDim.x相当于block的width。

blockIdx.y是指block在grid中竖排的位置,同理,blockIdx.x是指block在grid中横排的位置。

 

 

 

转载于:https://www.cnblogs.com/qingsunny/p/3384779.html

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

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

相关文章

用PyQt实现透明桌面时钟小部件

2019独角兽企业重金招聘Python工程师标准>>> #!/usr/bin/env python # -*- coding: utf-8 -*-Created on 2012-4-6author: wangxiaoimport sys from PyQt4 import QtGui, QtCore from PyQt4.QtCore import Qt from PyQt4.QtCore import QPoint from PyQt4.QtCore…

实现织梦dedecms百度主动推送(实时)网页抓取

做百度推广的时候&#xff0c;如何让百度快速收录呢&#xff0c;下面提供了三种方式&#xff0c;今天我们主要讲的是第一种。 如何选择链接提交方式 1、主动推送&#xff1a;最为快速的提交方式&#xff0c;推荐您将站点当天新产出链接立即通过此方式推送给百度&#xff0c;以保…

【RK3399Pro学习笔记】十八、点亮LED灯(python、C语言、bash)

目录GPIOpython3python-peripherypython2RPiC语言SysFs方式编写gpiolib.cgpiolib.hmain.c编译测试wiringPibash平台&#xff1a;华硕 Thinker Edge R 瑞芯微 RK3399Pro 固件版本&#xff1a;Tinker_Edge_R-Debian-Stretch-V1.0.4-20200615 GPIO (机翻)下表显示了座子的引脚&am…

Linux中python、C++和C语言的多线程用法整理(_thread、threading、thread和pthread)

目录python3开始学习Python线程_thread常量和函数&#xff1a;锁对象试用基本功能试用线程同步threading函数常量类线程本地数据线程对象锁对象递归锁对象条件对象信号量对象Semaphore 例子事件对象定时器对象栅栏对象在 with 语句中使用锁、条件和信号量测试Cstd::threadstd::…

Swing-BoxLayout用法-入门

注&#xff1a;本文内容源于http://www.java3z.com/cwbwebhome/article/article20/200016.html?id4797&#xff1b;细节内容根据笔者理解有修改。 BoxLayout 可以把控件依次进行水平或者垂直排列布局&#xff0c;这是通过参数 X_AXIS、Y_AXIS 来决定的。X_AXIS 表示水平排列&a…

Python开发利器之UliPad

一、安装Ulipad 因为ulipad编辑器使用的是wxpython编写的gui&#xff0c;所以我们需要第三方库wxpython的支持&#xff0c;先讲一下Ulipad在Windows系统环境下的安装&#xff1a; 1. 确实自己的windows版本&#xff0c;32位还是64位的。2. 查看自己安装的 Python版本&#xff0…

flask接收前台的form数据

html 记得访问从服务里打开 表单html 不能直接打开表单html https://www.cnblogs.com/wanghaonull/p/6340096.html

树莓派Raspbian Buster/Debian 10 安装ROS

目录一些补充安装ROS初始化rosdep测试平台&#xff1a;树莓派4B 系统版本&#xff1a; 2020-05-27-raspios-buster-arm64.img 一些补充 系统安装参考 【树莓派学习笔记】一、烧录系统、(无屏幕)配置Wifi和SSH服务 【树莓派学习笔记】二、(无屏幕)SSH远程登录、图形界面及系统…

树莓派安装Ubuntu MATE及ROS系统

目录解锁SSH换源安装VNC服务安装ROS初始化rosdep和环境测试平台&#xff1a;树莓派4B 系统版本&#xff1a; ubuntu-mate-20.04.1-desktop-armhfraspi.img 在Raspberry Pi Download Options下载系统镜像 在树莓派资源下载 | 树莓派实验室下载工具 使用SDForm…

jQuery学习笔记(四)

jQuery对表单、表格的操作及更多应用 表单应用 一个表单组成部分&#xff1a; 表单标签、表单域及表单按钮 单行文本框应用获取和失去焦点事件 $(function(){ $(":input").focus(function(){ //获取焦点触发事件 $(this).addClass("focus"); //增加样…

Flask最强攻略 - 跟DragonFire学Flask - 第四篇 Flask 中的模板语言 Jinja2 及 render_template 的深度用法

https://www.cnblogs.com/DragonFire/p/9259999.html 是时候开始写个前端了,Flask中默认的模板语言是Jinja2 现在我们来一步一步的学习一下 Jinja2 捎带手把 render_template 中留下的疑问解决一下 首先我们要在后端定义几个字符串,用于传递到前端 STUDENT {name: Old, age:…

【Jetson Nano学习笔记】1. 系统镜像和ROS的安装

目录安装系统换源安装VNC服务安装ROS初始化rosdep和环境测试平台&#xff1a;Jetson Nano 系统版本&#xff1a;4.6.1 安装系统 在Jetson Download Center下载镜像&#xff1a; 在树莓派资源下载 | 树莓派实验室下载工具 使用SDFormatter格式化内存卡 使用balenaEtcher烧录镜…

我的Android进阶之旅------Android利用Sensor(传感器)实现水平仪功能的小例

这里介绍的水平仪&#xff0c;指的是比较传统的气泡水平仪&#xff0c;在一个透明圆盘内充满液体&#xff0c;液体中留有一个气泡&#xff0c;当一端翘起时&#xff0c;该气泡就会浮向翘起的一端。 利用方向传感器返回的第一个参数&#xff0c;实现了一个指南针小应用。我的And…

【Jetson Nano学习笔记】2. ORB-SLAM3及ZED 2i驱动安装

目录ZED 2i驱动安装安装驱动自测ROS测试zed2i.launchrostopic listrosnode listdisplay_zed2i.launchzed_rtabmap.launchORB-SLAM3安装OpenCV 3安装Glew安装Pangolin安装boost安装Eigen 3安装OpenGL安装openssl安装ORB-SLAM3建立swap准备编译编译关闭swap平台&#xff1a;Jetso…

proj1088

滑雪Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 69608 Accepted: 25669Description Michael喜欢滑雪百这并不奇怪&#xff0c; 因为滑雪的确很刺激。可是为了获得速度&#xff0c;滑的区域必须向下倾斜&#xff0c;而且当你滑到坡底&#xff0c;你不得不再次走…

【Jetson Nano学习笔记】3. ORB-SLAM3运行双目Demo(ZED 2i)

目录修改zed-ros-wrapper的参数双目测试平台&#xff1a;Jetson Nano 系统版本&#xff1a;4.6.1 参考资料&#xff1a; zed-ros-wrapper —— ROS Wiki ZED 相机 && ORB-SLAM2安装环境配置与ROS下的调试 —— 李小铭 又一遍……ORB_SLAM2ZED相机(SDK2.2.1)CUDA9.0ROS…

MySQL数据库和ACID模型

2019独角兽企业重金招聘Python工程师标准>>> ACID模型是一组强调高可靠性的数据库系统设计原则。InnoDB存储引擎坚持ACID原则&#xff0c;确保即使在软件崩溃甚至是硬件故障的情况下&#xff0c;数据也不会损坏。当你需要依赖兼容ACID原则的业务时&#xff0c;你不必…

【Jetson Nano学习笔记】4. python 3编译bridge

目录使用python3编译boostconsole_bridgepython3bridge平台&#xff1a;Jetson Nano 系统版本&#xff1a;4.6.1 参考资料&#xff1a; How to setup ROS with Python 3 Unable to use cv_bridge with ROS Kinetic and Python3 CMake Error &#xff1a;Could not find a pac…

python time模块详解

2019独角兽企业重金招聘Python工程师标准>>> python time模块详解 分类&#xff1a; python2009-03-28 23:35 89831人阅读 评论(9) 收藏 举报 pythonstructstringdstimportdate python 的内嵌time模板翻译及说明 一、简介 time模块提供各种操作时间的函数 说明&am…

【RK3399Pro学习笔记】十九、在ROS中点亮LED灯

目录创建ROS工作空间创建ROS功能包CSysFs方式&#xff08;需root&#xff09;源文件blink.cppgpiolib.cpp头文件gpiolib.hCMakeLists.txt运行代码调用shell命令方式&#xff08;无需root&#xff09;源文件blink.cppCMakeLists.txt运行代码平台&#xff1a;华硕 Thinker Edge R…