Page 71 - 《软件学报》2020年第10期
P. 71
张鸿骏 等:一种适应 GPU 的混合访问缓存索引框架 3047
们采用的 CUDA 9.1 版本的 GPU 编程框架,代码行数共计 1 385 行,其中接入库函数与数据存储区域初始化函
数为 324 行,GPU kernel 函数为 953 行,其余为宏定义及全局变量索引.
实现的方法与功能描述见表 1 和表 2.表 1 给出了在 CPU 上实现的函数,主要包含用于其他 CPU 程序调用
进行键值操作的接入库函数、CPU 与 GPU 存储区域索引与内容初始化的数据初始化函数,以及向 GPU kernel
函数提交任务与键值数据的函数.CPU 上的函数主要向其他程序提供了键值数据操作的接口,对 GPU 上的
kernel 函数进行了封装,实现了其他程序调用时对 GPU 操作的透明化.表 2 给出了 GPU 上的 kernel 函数.主
要包含了 GPU 用于接收与解析 CPU 提交键值操作任务和数据的 global 函数、散列表操作的 device 函数、
缓存队列踢出操作的 device 函数.GPU 上实现的 kernel 函数用于在 GPU 存储区域中的散列表上处理对应的
键值数据.
Table 1 Interface and implemented methods on CPU
表 1 CPU 接口与实现函数
方法名 功能描述
set 插入键值数据
get 查询键值数据
del 删除键值数据
CCHT_init 初始化 CPU 数据结构与 GPU 存储索引区域
flush_ops 向 GPU 提交在缓冲区中待执行的操作与键值数据,其中,每个任务包含请求操作类型标识
Table 2 Kernel method on GPU
表 2 GPU 核函数
方法名 功能描述
CCHT_process global 函数,用于 CPU 向 GPU 提交键值处理任务,解析任务类型并执行相应 device 函数
CCHT_set device 函数,用于将数据插入散列表
CCHT_get device 函数,用于查询并获取散列表中的目标键值数据
CCHT_del device 函数,用于删除散列表中的目标数据
CCHT_evict device 函数,用于踢出散列表缓存队列中末尾的数据
hash1,hash2 device 函数,用于计算键数据散列值
CCHT 在 GPU 上的操作仅包括 CCHT_set、CCHT_get、CCHT_del 和 CCHT_evict 这 4 个分支核函数操
作,符合 GPU 以单指令多线程(single instruction multiple thread,简称 SIMT)形式执行.CCHT 在 CPUGPU 异构环
境下执行可以获得更好的并发性能.
4.3 实现细节
在数据存储区域初始化时,采用 malloc 与 cudaMalloc 分配所需存储区域.其中包含了在 CPU 上执行缓存操
作与键值数据的存储区域、GPU 执行结果返回的存储区域;在 GPU 上接受执行操作与键值数据的存储区域、
以槽为单元的散列表键值数据存储区域、桶中标识的存储区域及散列表操作执行结果的存储区域.在完成分配
后,通过 memset 与 cudaMemset 实现数据存储区域的初始化.
在 CPU 上操作键值数据的函数,将其他程序调用传递进的键值数据与操作,复制至CPU内存中的键值数据与
任务的缓冲队列中.所有操作键值数据的函数共用同一数据与任务缓冲队列,允许任务缓冲队列中包含多个写操
作和多个读操作.当达到向 GPU 提交任务数的阈值时,则调用 flush_ops 函数,通过 global 函数 CCHT_process 向
GPU 传递数据及相应的操作标识.当向 GPU 提交的任务执行完成后,将结果返回至指定的存储区域.在 CPU 上
运行的程序对结果进一步处理,如判断读操作是否命中、更新可用缓存空间大小等.
在 GPU 上执行核函数时,每个核函数线程执行单一任务及键值数据操作,根据 GPU 线程的全局 id 进行指
定,CCHT_process 接受传递进入 GPU 内存的键值数据及任务数据,并根据任务数据的标识进行解析,以获取操
作类型.对不同的散列表操作选择调用 CCHT_set、CCHT_get 或 CCHT_del,完成后将结果返回至指定的 GPU
内存存储区域.当内存缓存空间已满时,CPU 传递的写操作的任务数据包含替换操作与写操作,GPU 在调用
CCHT_evict 执行踢出操作后,再调用 CCHT_set 进行写操作.