CUDA Toolkit Documentation (nvidia.com)

  • host CPU和内存 (host memory)
  • Device GPU和显存 (device memory)

SIMT模型与SIMD模型的区别

SIMD(Single Instruction Multi Data,单指令多数据)模型要求同一个向量中的所有元素要在统一的同步组中一起执行,而SIMT则允许属于同一个线程束的多个线程独立执行,这几个线程可以有不同的行为。因此SIMT(Single Instruction Multi Thread)允许线程级并发,也就是在统一线程束下的线程可以同时做不同的事情。

SIMT有SIMD所不具备的三个特征:

  1. 每个线程都有自己的指令地址计数器
  2. 每个线程都有自己的寄存器状态
  3. 每个线程可以有一个独立的执行路径

硬件基础

系统每一bit的输入与输出,包括磁盘、网络控制器、键盘、鼠标、USB设备以及GPU的输入输出,都要通过芯片组。直到最近,芯片组被一分为二:一个是连接大多数外围设备和系统的“南桥”,另一个是包含图形总线(加速图形端口,后被PCIe接口取代)和内存控制器(通过前端总线与内存相连)的“北桥”。

外部数据总线是中央处理器CPU(Central Processing Unit)的一部分,是CPU与外部数据传输的通道。外部数据总线一次可传输二进制数据的位数越大,CPU与外部交换数据的能力越强。

GPU内存控制器总是和GPU集成,它是在一个与CPU内存控制器完全不同的约束集下设计。



CPU的缺陷

CPU 与 GPU 架构的一个主要区别就是 CPU 与 GPU 映射寄存器的方式。 CPU 通过使用寄存器重命名和栈来执行多线程。为了运行个新任务, CPU 需要进行上下文切换,将当前所有寄存器的状态保存到栈(系统内存)上,然后从栈中恢复当前需要执行的新线程上次的执行状态。这些操作通常需要花费上百个 CPU 时钟周期。如果在 CPU 上开启过多的线程,时间儿乎都将花费在上下文切换过程中寄存器内容的换进/换出操作上。因此,如果在 CPU 开启过多的线程,有效工作的吞吐量将会快速降低。
然而, GPU 却恰恰相反。 GPU 利用多线程隐藏了内存获取与指令执行带来的延迟。因此,在 GPU 上开启过少的线程反而会因为等待内存事务使 GPU 处于闲置状态。此外, GPU 也不使用寄存器重命名的机制,而是致力于为每一个线程都分配真实的寄存器。因此,当需要上下文切换时,所需要的操作就是将指向当前寄存器组的选择器(或指针)更新,以指向下一个执行的线程束的寄存器组,因此儿乎是零开销。
一个线程束即同时调度的一组线程。在当前的硬件中,一个线程束包含32个线程。因此,在一个 SM 中,每次换进/换出、调度都是32个线程同时执行。
每个 SM 能调度若干个线程块。在 SM 层,线程块即若干个独立线程束的逻辑组。编译时会计算出每个内核线程需要的寄存器数目。所有的线程块都具有相同的大小,并拥有已知数目的线程,每个线程块需要的寄存器数目也就是已知和固定的。因此, GPU 就能为在硬件上调度的线程块分配固定数目的寄存器组。

线程层次

每32线程分为一个warp

GigaThread/Grid:GPU级别的调度单位,共享L2级别的Cache

SM(Streaming Multiprocessor)/block:SM调度block(线程块),共享L1级别的Cache

Warp/Threads:一个Warp包含32个hread,Warp是CUDA core级别(一个thread对应一个CUDA core,但一个CUDA core可以通过分时复用的方式实现多个thread)的调度单位,允许同一个warp中的thread读取其他thread的值,共享L0级别的Cache

每一个warp共享一个contex执行上下文 取指译码器

  • Thread : sequential execution unit

    • 所有线程执行相同的核函数
    • 并行执行
  • Block : a group of threads

    • 执行在同一个SM(Streaming Multiprocessor)
    • 同一个Block中的线程共享一块Shared Memory(L1级别的Cache)
    • CUDA不支持超过1024个线程的线程块
  • Grid : a collection of thread blocks

    • 一个Grid当中的Block可以在多个SM中执行,一个SM可以有很多Block

每个SM所能容纳的block数量受到以下两方面限制:

  • 每个SM可提供的寄存器空间固定。
    如果每个线程所需的寄存器过多,则每个SM能够调度的线程数量就受到限制。
  • 每个SM能够调度的线程束的数量有限制。

CUDA的执行流程

  1. 加载核函数
  2. 将Grid分配到一个Device(GPU)
  3. 根据<<<…>>>内的第一个参数,Giga thread eigine将block分配到SM中。一个Block内的线程一定会在同一个SM内,一个SM可以有很多Block。
  4. 根据<<<…>>>内的第二个参数,Warp调度器将调用线程
  5. Warp调度器为了提高运行效率,会将每32个线程分为一组,称作一个warp。block(x,y,z)按先X方向,再Y方向,再Z方向优先组合成warp
  6. 每个warp会被分配到32个Core上运行。

CPU与GPU交互、多GPU间交互原理

Page-locked or pinned memory transfers attain the highest bandwidth between the host and the device.

Pinned memory is allocated using the cudaHostAlloc() functions in the Runtime API.

cudaHostRegister() 可以将host memory变为锁页内存.

计算和内存拷贝异步执行

cudaMemcpy()是主机内存与设备内存间阻塞式数据传输的API,只有当数据传输完成后才会将控制权返回主机线程。

cudaMemcpyAsync()是主机锁页内存与设备内存间非阻塞式数据传输的API,会立即将控制器返回主机线程。比cudaMemcpy()多一个参数Stream ID.

  • 锁页主机内存:GPU可以直接访问的CPU内存;
  • 命令缓冲区:由CUDA驱动程序写入命令,GPU从此缓冲区读取命令并控制其执行;
  • CPU/GPU同步:指的是CPU如何跟踪GPU的进度。

CPU/GPU并发

CUDA内核的所有启动都是异步的:CPU通过将命令写入命令缓冲区来请求启动内核,然后直接返回,而不检查GPU进度。内存复制也可以采用异步方式,这使CPU/GPU并发以及可能使内存复制与内核处理并发执行。

命令缓冲区和同步位置都位于锁页主机内存上,被CUDA驱动程序和GPU使用,以跟踪相应进程。主要的GPU操作后都跟着一个将新进度值写入共享同步位置的命令。如下图所示,进度值将一直为3,直到GPU完成当前命令的执行并将4写人同步位置中为止。

CUDA既隐式又显式地暴露了这些硬件功能。上下文范围的同步通过简单调用cuCtxSynchronize()、cudaThreadSynchronize()等函数来检查GPU请求的最近同步值,并且一直等待,直到同步位置获得该值。例如,在下图中,如果由CPU写人的命令8之后紧接着cuCtxSynchronize()或cudaThreadSynchronize()函数,则驱动程序将一直等待,直到共享同步值大于或等于8为止。

CUDA 事件则更明确地暴露了这些硬件能力。cuEventRecord()函数的作用是将一个命令加入队列使得一个新的同步值写人共享同步位置中,cuEventQuery()和 cuEventSynchronize()则分别用于检查和等待这个事件的同步值。早期版本的 CUDA 只是简单地轮询共享的同步位置,反复地读内存,直到等待准则满足为止。但是这种方法代价很大,且只有当应用程序不必等待太久时才有用(即同步位置不一定要被读取很多遍,就可以因等待标准已经得到满足而退出)。对大多数应用程序来说,基于中断的方案( CUDA 公开称为“阻塞同步”)更好,因为它们使 CPU 等待线程挂起,直到 GPU 发出中断信号为止。驱动程序将 GPU 中断映射到一个特定的线程同步原语平台,如Win32事件或 Linux 的信号。
通过指定 CU_CTX _BLOCKING_SYNC 到 cuCtxCreate()或指定 cudaDeviceBlockingSync 到 cudaSetDeviceFlags(),应用程序可以强制使用上下文范围的同步进人阻塞状态。然而,使用阻塞的 CUDA 事件(指定 CU_EVENT_BLOCKING_SYNC 到 cuEventCreate()或指定 cudaEventBlockingSync 到 cudaEventCreate() )更可取,因为它们粒度更细且可以与任何类型的 CUDA 上下文进行无缝互操作。
敏锐的读者可能会关注 CPU 和 GPU 在不使用原子操作或其他同步原语的情况下读取和写人这种共享的内存位置。但由于 CPU 只读取共享位置,竞争条件并不是关注点。这样,最坏的情况是 CPU 读取了一个“过时的”值,从而导致其等待时间要比实际的长。

CPU接口与内部GPU同步

GPU 可能包含多个引擎,以使内核执行和内存复制并发进行。在这种情况下, GPU 的驱动程序将写人一些命令,这些命令被分发到同时运行的不同引擎中。每个引擎都有自己的命令缓冲区和共享同步值。图2-28显示的是两个复制引擎和一个计算引擎并行工作时的情形。其中,主机接口负责读取命令并将其调度到相应引擎。在图2-28中,一个主机到设备的内存复制操作和两个相关操作(一个内核启动和一个设备到主机的内存复制)已被提交给硬件。依据 CUDA 编程抽象模型,这些操作都是在同一个流上进行的。这个流就像是一个 CPU 线程,在内存复制之后接受内核启动的提交。因此, CUDA 驱动程序为了实现内部 GPU 同步必须将命令插入主机接口的命令流中。

如上图所示,主机接口在协调流同步需求上起着核心作用。例如,在完成所需的内存复制之前,内核是启动不了的。此时,DMA单元可以停止给既定引擎传递命令,直到同步位置获得一个特定值为止。此操作与 CPU / GPU 同步类似,但 GPU 是对它内部进行同步的。

此硬件机制之上的软件抽象模型是一个 CUDA 流。它在该操作中就像 CPU 线程一样都是串行排队,为了并发执行需要多个流。由于引擎间共享命令缓冲区,应用程同的流里以软件的方式流水线化它们的请求。

GPU间同步

由于图2-26-图2-28中的同步位置都是在主机内存上,所以它们可以被系统中的任何一个 GPU 访问。其结果是,在CUDA4.0中,英伟达能够在cudaStreamWaitEvent()和 cuStreamWaiEvent() 函数的形式中添加 GPU 之间的同步。这些 API调用导致驱动程序为主机接口将等待命令插人当前 GPu 的命令缓冲区中,使得 GPU 一直等待,直到事件的给定同步值被写入为止。从CUDA4.0开始,事件不一定会被等待中的同一个 GPU用信号唤醒。流原先只能在单个 GPU 的硬件单元之间同步执行,现在已提升到可以在 GPU 之间同步执行了。

GPU异构计算基础知识相关推荐

  1. GPU并行计算基础知识科普

    1.什么是异构架构? 使用CPU,GPU等两种或多种不同的硬件架构结合在一起完成计算任务. 说白了就是CPU内部组织 和 GPU内部组织不一样,即"异构". 2.什么叫GPU通用计 ...

  2. GPU硬件知识和基础概念 : AI时代程序员都应该了解的GPU基础知识

    金融建模.自动驾驶.智能机器人.新材料发现.脑神经科学.医学影像分析-人工智能时代的科学研究极度依赖计算力的支持.提供算力的各家硬件芯片厂商中,最抢镜的当属英伟达Nvidia了.这家做显卡起家的芯片公 ...

  3. 详解服务器异构计算FPGA基础知识

    随着云计算,大数据和人工智能技术应用,单靠CPU已经无法满足各行各业的算力需求.海量数据分析.机器学习和边缘计算等场景需要计算架构多样化,需要不同的处理器架构和GPU,NPU和FPGA等异构计算技术协 ...

  4. 【西川善司的3D图形技术连载】GPU和Shader技术的基础知识(1~8回)

    本连载的主要目的,是介绍最新的PC和GAME所使用的最新3D图形技术的发展趋势. 暂时的方针是,首先是考虑介绍比较新的PC Game和PS3,XBOX360等新时代游戏机的游戏所采用的技术. 那么首先 ...

  5. 【西川善司】GPU和Shader技术的基础知识(全8回)

    本文取自西川善司的3D图形技术连载,全99回 本贴为1~8回,争取每1~2天更新一回吧.半年更新完. 也希望大家能支持. 翻译 Trace 校对&注解 千里马肝 http://www.open ...

  6. 关于实现Halcon算法加速的基础知识(多核并行/GPU)

    一.提高Halcon的运算速度,有以下几种方法: 1.Multithreading(多线程) 2.Automatic Parallelization(自动操作并行化) 3.Compute device ...

  7. OpenCV算法加速(1)OpenMP/PPL/TTB基础知识

    一.提高OpenCV的运算速度,有以下几种方法: 1.利用x86转为x64提速,可以提高1倍的速度 2.多线程的openmp或Intel TBB提速,将cpu的利用率从20%多提高到100% 3.利用 ...

  8. JS基础知识学习(一)

    JS基础知识 前端开发常用的浏览器 谷歌浏览器(chrome):Webkit内核(v8引擎) 火狐浏览器(firefox):Gecko内核 欧朋浏览器(opera):Presto内核 IE浏览器:Tr ...

  9. DL:深度学习(神经网络)的简介、基础知识(神经元/感知机、训练策略、预测原理)、算法分类、经典案例应用之详细攻略

    DL:深度学习(神经网络)的简介.基础知识(神经元/感知机.训练策略.预测原理).算法分类.经典案例应用之详细攻略 目录 深度学习(神经网络)的简介 1.深度学习浪潮兴起的三大因素 深度学习(神经网络 ...

最新文章

  1. SD卡中FAT32文件格式快速入门(图文详细介绍)
  2. 使用SecureCRT的SFTP在WINDOWS与LINUX之间传输文件(转载)
  3. 查询删除的外向交货单
  4. BlazeDS 整合 Flex HelloWorld 示例
  5. PAT 1016 部分A+B
  6. IOS动态库打包导入工程报错Library not loaded: @rpath/SwiftFrame.framework/SwiftFrame
  7. POJ3764 The xor-longest Path(Trie树)
  8. 爱链工具怎么使用 爱链工具详细使用图文教程
  9. 清华大学计算机科学与技术在哪个楼,清华大学计算机科学与技术系宿舍
  10. Python爬虫连载16-OCR工具Tesseract、Scrapt初步
  11. document-scanner:一个基于OpenCV的文档扫描器
  12. 设计模式C++实现——工厂模式
  13. 【前端学习】HTML入门
  14. 爬取校花图片保存到本地文件夹下(requests+re)
  15. Thinkphp内核开发盲盒商城源码v2.0 对接易支付/阿里云短信/七牛云存储
  16. 【CV系列】图像算法之一:Randon变换
  17. 赚钱App研究之格式转换类app
  18. 【Solved】syntax error near unexpected token done
  19. iOS内存管理—MRC
  20. 2019最新Android常用开源库总结

热门文章

  1. python什么是关键字参数_Python函数关键字参数
  2. 北京大学计算机博士金钊,她是北大工科博士生,颜值胜过学霸武亦姝,深受理科男生的喜爱...
  3. wk算法-SAR成像算法系列(五)
  4. Leetcode刷题 2021.01.22
  5. ADS解决xxxis an undefined model
  6. static struct、typedef struct
  7. 哈密顿系统_Matlab
  8. RPM包rpmbuild SPEC文件深度说明
  9. 用python把Excel表中不同货币的资金换算成人民币
  10. 电影天堂影片下载地址获取