GPU是一个外围设备,本来是专门作为图形渲染使用的,但是随着其功能的越来越强大,GPU也逐渐成为继CPU之后的又一计算核心。但不同于CPU的架构设计,GPU的架构从一开始就更倾向于图形渲染和大规模数据的并行计算处理。而大规模的并行计算,离不开大规模的数据传输,只有深入了解了GPU的存储体系,才能真正发挥GPU的威力,写出高性能的软件产品。但是由于GPU存储体系相关的资料非常少,加之非常分散,所以在看了大量的零散资料后,想通过这篇文章,总结一下关于GPU存储相关的知识点,以期达到加深理解的目的。

GPU存储体系的设计哲学是更大的内存带宽,而不是更低的访问延迟。该设计原则不同于CPU依赖多级Cache来降低内存访问延迟的策略,GPU则是通过大量的并行线程来规避或者叫隐藏内存访问的延迟,具体来说就是GPU在等待某个内存数据到来的时候,会运行成百上千个其他与该数据无关的线程,来处理另外的数据请求,这就是GPU存储体系内存访问的特点:高带宽,高延迟。

正式开始之前,我们需要了解几个基础的概念。我们通常在讲内存时,多数情况下都是指CPU的专用存储,从GPU存储的角度来说,CPU的内存一般称之为主存(main memory),GPU自己的存储则称为local memory,即GPU的本地存储,有时候也称为video memory。

GPU的存储体系根据GPU的类型不同,可以是逻辑上的,也可以是物理上的。对于集成显卡(即integrated GPU)而言,例如 Intel HD Graphics ,GPU和CPU位于同一die中,所以它没有自己的物理存储设备,而是共享CPU的存储空间,即Unified Memory Architecture(一致性存储架构),通常是从CPU的存储中划分一部分出来作为该GPU的local memory;另一种显卡称为独立显卡(即dedicated GPU),像Nvidia和AMD生产的GPU就属于这类,它们都拥有自己的物理存储设备,是我们日常使用最多的GPU类型了。无论哪种GPU,它都拥有自己的一套地址空间,且独立于CPU的虚拟内存地址空间。GPU地址空间的管理是通过内核态驱动来完成的,例如Windows上的KMD(Kernel-Mode Driver)

对于integrated gpu而言,因为GPU和CPU处于同一die中,所以GPU和CPU很多时候是共享总线的。除了GPU自己的local memory之外,CPU和GPU之间有时候需要共享一些数据,例如在渲染的时候,CPU将顶点数据放入主存当中,供GPU使用。由于主存的内容对GPU来说是不可见的,所以GPU是不能直接访问这些数据的。为了让GPU访问CPU主存的内容,业界引入了一个叫GART(即Graphic Address Remapping Table)的技术。GART是一个 I/O memory management unit (IOMMU) ,说白了就是一个内存地址的映射表,可以将CPU的内存地址重新映射到GPU的地址空间,这样就可以让显卡直接访问(DMA,direct memory access)host system memory。

反过来,CPU如何访问GPU的存储空间呢?因为integrated gpu的存储空间是从主存分出的一部分,一般情况下都比较小,OS可以将GPU的整个存储空间映射到CPU的地址空间。但是对于dedicated gpu来说,这种方式就不行了,因为独立显卡的显存一般比较大,一个32位的OS整个地址空间也才4GB。所以独立显卡拥有与integrated gpu不同的地址空间映射机制,用于解决这个问题。一种比较常用的方式是映射一部分GPU存储空间到CPU的地址空间,典型大小为256MB/512MB,这段地址空间会通过PCIe的bar获取一个CPU可见的地址空间。最新的PCIe支持 resize bar技术,支持该技术的GPU可以动态调整映射区域的大小。

简单介绍完GPU的存储体系后,我以OpenGL程序为例,来分析一下OpenGL中数据的upload和download过程,从而了解GPU存储体系在实际程序中的运用。

OpenGL更新数据的常用函数家族是:glBuffer*Data和glMapBuffer*。更准确的说是CPU需要更新数据给GPU使用时,顶点数据的更新,纹理数据的上传等等,需要CPU到GPU的数据传输,这个过程称为streaming。这个数据传输的过程有两种方式:

l  glBufferData/glBufferSubData

通过这两个函数,可以将数据从main memory拷贝到pinned memory,一旦拷贝完成,就会发起一次异步的DMA(Direct Memory Access)传输,将数据传输给GPU,然后就会从函数调用返回,一旦函数返回,你就可以对原来CPU主存中的数据做任何处理,修改或者删除。

l  glMap*/glUnmap*

通过mapping的方式传输数据,你可以获取一个指向pinned memory的指针,通过该指针你可以拷贝main memory上的数据到pinned memory,然后调用glUnmap通知driver你已经完成数据的更新,这种方式看似跟上面的glBufferData/glBufferSubData一样,但是你可以获得更多的控制权。

该例子中的pinned memory就是CPU内存上的一块专门用于GART的存储区域,DMA传输则是通过上文提到的PCIe bar来实现的,了解了GPU的存储体系,在使用图形API进行渲染绘制时,才能清晰的了解数据的归属和流向,从而避免不必要的错误和性能损失。

参考链接:

https://www.makeuseof.com/tag/can-shared-graphics-finally-compete-with-a-dedicated-graphics-card/

https://lwn.net/Articles/257417/

https://zhuanlan.zhihu.com/p/35891701

https://fgiesen.wordpress.com/2011/07/01/a-trip-through-the-graphics-pipeline-2011-part-1/

GPU体系架构(二):GPU存储体系的更多相关文章

  1. 深入GPU硬件架构及运行机制

    目录 一.导言 1.1 为何要了解GPU? 1.2 内容要点 1.3 带着问题阅读 二.GPU概述 2.1 GPU是什么? 2.2 GPU历史 2.2.1 NV GPU发展史 2.2.2 NV GPU ...

  2. android体系架构

    android体系架构总结: android体系架构分为四层 第一层:应用层:applications 第二层:开发层 第三层:

  3. hbase的存储体系

    一.了解hbase的存储体系. hbase的存储体系核心的有Split机制,Flush机制和Compact机制. 1.split机制 每一个hbase的table表在刚刚开始的时候,只有一个regio ...

  4. NUMA 体系架构

    NUMA 体系架构 SMP 体系架构 NUMA 体系架构 NUMA 结构基本概念 Openstack flavor NUMA 策略 Nova 实现 NUMA 流程 1. SMP 体系架构 CPU 计算 ...

  5. 2020再见&新的计划(建立Android体系架构)

    2020,再见 关于2020,我心中有四个关键词: 疫情 年初突如其来的疫情,打破了原本生活的节奏,也没想到会笼罩全世界整整一年,希望这个世界早点好起来吧. 科比 初三的早晨,噩耗传来,我一度不敢相信 ...

  6. GPU体系架构(一):数据的并行处理

    最近在了解GPU架构这方面的内容,由于资料零零散散,所以准备写两篇博客整理一下.GPU的架构复杂无比,这两篇文章也是从宏观的层面去一窥GPU的工作原理罢了 GPU根据厂商的不同,显卡型号的不同,GPU ...

  7. InnoDB体系架构(二)内存

    InnoDB体系架构(二)内存 上篇文章 InnoDB体系架构(一)后台线程 介绍了MySQL InnoDB存储引擎后台线程:Master Thread.IO Thread.Purge Thread. ...

  8. MySQL InnoDB存储引擎体系架构 —— 索引高级

    转载地址:https://mp.weixin.qq.com/s/HNnzAgUtBoDhhJpsA0fjKQ 世界上只两件东西能震撼人们的心灵:一件是我们心中崇高的道德标准:另一件是我们头顶上灿烂的星 ...

  9. F2工作流引擎这工作流引擎体系架构(二)

    F2工作流体系架构概览图 为了能更好的了解F2工作流引擎的架构体系,花了些时间画了整个架构的体系图.F2工作流引擎遵循参考WFCM规范,目标是实现轻量级的工作流引擎,支持多种数据库及快速应用到任何基于 ...

随机推荐

  1. ip 地址库 这个 准么 呢

  2. hge引擎使用技巧

    图片周围最好留出一像素,即上下左右都多出一像素.然后使用pngopt.exe处理一下.这样可以减少图片拉伸.旋转时边界模糊的情况 图片宽高最好是 2的N次方

  3. 创建dynamics CRM client-side (八) - 获取attribute的值 和 设置disable

    大家可以用下面的方式来获取attribute的值 formContext.getAttribute("address1_shippingmethodcode").getText() ...

  4. 通过识别页面内容获得返回值判断后续执行(exists指令的用法)

    本案例主要用到airtest 的exists指令 从指令解释可以知道,当判断某图片不存在的时候,会返回false值 脚本思路即为如果返回值==false则执行A,!=fales则执行B 下图脚本思路, ...

  5. Servlet梳理

    Servlet 梳理 概述 Web 技术成为当今主流的互联网 Web 应用技术之一,而 Servlet 是 Java Web 技术的核心基础. 要介绍 Servlet 必须要先把 Servlet 容器 ...

  6. CTF--HTTP服务--路径遍历(拿到www-data用户权限)

    开门见山 1. 扫描靶机ip,发现PCS 172.18.4.20 2. 用nmap扫描靶机开放服务及版本 3. 再扫描靶机的全部信息 4. 用nikto工具探测http服务敏感信息 5. 用dirb工 ...

  7. python(从放弃到从头开始)

    本节内容 Python介绍 发展史 Python 2 or 3? Hello World程序 变量 用户输入 .pyc是个什么鬼? 数据类型初识 数据运算 表达式if ...else语句 表达式for ...

  8. Git详解之Git起步

    前言 本章介绍开始使用 Git 前的相关知识.我们会先了解一些版本控制工具的历史背景,然后试着让 Git 在你的系统上跑起来,直到最后配置好,可以正常开始开发工作.读完本章,你就会明白为什么 Git ...

  9. linux系统CentOS7中find命令使用

    一.作用 查找文件或目录 二.参数(常用) -atime 查找在指定时间曾被存取过的目录或文件,单位以24小时计算.(访问时间,执行文件等) -ctime 查找指定时间曾被更改的目录或文件,单位以24 ...

  10. linux --- 杀掉特定端口进程与启用SSH服务

    Linux下端口被占用解决 有时候关闭软件后,后台进程死掉,导致端口被占用.下面以JBoss端口8083被占用为例,列出详细解决过程. 解决方法: 1.查找被占用的端口 netstat -tln ne ...