EMOGI: Efficient Memory-access for Out-of-memory Graph-traversal In GPUs 阅读笔记

要开始做毕设,毕设的内容是基于GPU的高效大规模图计算,先读一下这个open problem中的优秀论文,写博客以记录学习。

使用GPU进行图遍历,图形常常不适合GPU内存。先前的工作要么使用输入数据预处理/分区,要么使用统一虚拟存储器(UVM)将数据块从主机存储器细化到GPU存储器。

大多数已有的工作将这些大型图存储在主机存储器中,并让GPU通过统一虚拟存储器(UVM)机制访问它们。UVM将CPU内存和GPU内存都带入一个单一的共享地址空间。UVM允许GPU简单地访问统一虚拟地址空间中的数据,并且它使用分页机制在主机内存和GPU内存之间透明地迁移所需的页面。

使用UVM进行图遍历的性能并不具有竞争力。这是因为在图遍历期间前往边列表的内存访问本质上是不规则的。

文章提出了一种新的基于零拷贝的图形遍历系统EMOGI,主要采用了两种优化,内存访问合并和内存访问对齐,可以应用于图遍历内核代码以最大化PCIe带宽。

内存访问合并:优化生成最大大小的PCIe请求到零拷贝内存
内存访问对齐:将所有翘曲(warp)移位到128字节边界来强制内存访问对齐。这是因为内存访问合并优化不能保证内存请求对齐。这种不对齐可能导致性能下降。

通过对PCIe3.0和PCIe4.0互连线的评估,我们发现EMOGI性能与CPU-GPU互连线带宽的提高呈线性关系。

文章采用顶点为中心的并行化遍历方式,在遍历开始前设置初始的活动顶点
作为GPU图遍历的输入图格式,文章使用压缩稀疏行(CSR)格式。CSR可以说是表示图的最流行的方法,因为它的内存很低,但是GPU图形上的内存不足图形遍历图形,即使是CSR格式,也可能比GPU内存大几个数量级。在这样的图上遍历是使用统一虚拟存储器(UVM),UVM提供一个单一的内存地址空间,CPU和GPU都可以通过页面错误机制访问。
但是这种方式存在以下问题
由于整个管理过程是单线程的,所以UVM页面迁移的整体性能严重依赖于主机CPU的单线程性能。UVM在图遍历中的低效表现在两个方面。首先,对于非常大的图形,由于有限的GPU内存容量会导致频繁的页面跳动,很难利用时间性。其次,在迭代中访问的顶点的相邻列表之间缺乏空间局部性,导致显著的I/O读取放大和更频繁的页面迁移。

为了允许GPU线程以比UVM更小的粒度访问外部存储器,GPU支持将存储器地址范围标记为零拷贝存储器。零复制(Zero-copy),也常被称为直接访问,不需要在外部存储器和GPU存储器之间进行任何页面迁移或复制。当GPU线程访问零拷贝内存,就像它是GPU全局内存一样,GPU通过外部互连(如PCIe)将来自线程的内存请求转换为内存请求。存储器请求的目标可以是系统中的任何位置,只要该位置可以被存储器映射到共享总线地址。

EMOGI旨在最大化零拷贝带宽。通过适当的实现,零拷贝几乎可以使PCIe带宽饱和。

跨行  合并并对齐    合并但并未对齐
合并并对齐:线程被分组到线程束中,每个线程束包含32个线程,一个warp中的线程访问输入数组128字节高速缓存行中的连续元素。这允许GPU合并单元自动将连续的32字节内存请求合并为单个更大的128字节PCIe请求(图(b))。使用128字节的PCIe请求,达到最大PCIe带宽变得容易得多

合并但未对齐:然而,对于所有实际情况,保证任何数据结构的128字节对齐可能是困难的。有可能一个线程束的起始索引没有与128字节边界对齐。某些线程束可能需要发出两个单独的PCle请求来获取单个128字节的高速缓存线。在最坏的情况下,如果线程束的存储器访问不是128字节对齐的,并且线程束访问存储器的连续区域,则未对齐可以级联到所有后续的曲面。不幸的是,这会导致所有线程束生成两个PCIe请求。如图©

那么我们可以很容易想到一个问题,为了利用零拷贝进行图遍历,我们最好至少需要128字节的空间局部性,以便最好地使用每次内存访问。

如果CSR数据类型分别为8字节或4字节,则单个128字节零拷贝访问可以有16或32个数据元素。

与UVM相比,UVM需要至少4KB的空间局部性(512或1024个数据元素),对于我们研究的图来说,找到16-32个空间局部性元素是合理的。

与UVM方法相比,Emogi的图遍历方法消除了页面错误的发生,并且减少了I/O放大,因为只移动了所需的字节。在以顶点为中心的图遍历方法中,在每次内核执行时,输入图被单个顶点深度遍历。因此,启动的核的总数,例如在广度优先搜索(BFS)的情况下,等于源顶点到最远可达顶点之间的距离。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
后台采用apache服务器下的cgi处理c语言做微信小程序后台逻辑的脚本映射。PC端的服务器和客户端都是基于c语言写的。采用mysql数据库进行用户数据和聊天记录的存储。.zip C语言是一种广泛使用的编程语言,它具有高效、灵活、可移植性强等特点,被广泛应用于操作系统、嵌入式系统、数据库、编译器等领域的开发。C语言的基本语法包括变量、数据类型、运算符、控制结构(如if语句、循环语句等)、函数、指针等。下面详细介绍C语言的基本概念和语法。 1. 变量和数据类型 在C语言中,变量用于存储数据,数据类型用于定义变量的类型和范围。C语言支持多种数据类型,包括基本数据类型(如int、float、char等)和复合数据类型(如结构体、联合等)。 2. 运算符 C语言中常用的运算符包括算术运算符(如+、、、/等)、关系运算符(如==、!=、、=、<、<=等)、逻辑运算符(如&&、||、!等)。此外,还有位运算符(如&、|、^等)和指针运算符(如、等)。 3. 控制结构 C语言中常用的控制结构包括if语句、循环语句(如for、while等)和switch语句。通过这些控制结构,可以实现程序的分支、循环和多路选择等功能。 4. 函数 函数是C语言中用于封装代码的单元,可以实现代码的复用和模块化。C语言中定义函数使用关键字“void”或返回值类型(如int、float等),并通过“{”和“}”括起来的代码块来实现函数的功能。 5. 指针 指针是C语言中用于存储变量地址的变量。通过指针,可以实现对内存的间接访问和修改。C语言中定义指针使用星号()符号,指向数组、字符串和结构体等数据结构时,还需要注意数组名和字符串常量的特殊性质。 6. 数组和字符串 数组是C语言中用于存储同类型数据的结构,可以通过索引访问和修改数组中的元素。字符串是C语言中用于存储文本数据的特殊类型,通常以字符串常量的形式出现,用双引号("...")括起来,末尾自动添加'\0'字符。 7. 结构体和联合 结构体和联合是C语言中用于存储不同类型数据的复合数据类型。结构体由多个成员组成,每个成员可以是不同的数据类型;联合由多个变量组成,它们共用同一块内存空间。通过结构体和联合,可以实现数据的封装和抽象。 8. 文件操作 C语言中通过文件操作函数(如fopen、fclose、fread、fwrite等)实现对文件的读写操作。文件操作函数通常返回文件指针,用于表示打开的文件。通过文件指针,可以进行文件的定位、读写等操作。 总之,C语言是一种功能强大、灵活高效的编程语言,广泛应用于各种领域。掌握C语言的基本语法和数据结构,可以为编程学习和实践打下坚实的基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值