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 进行写操作.
   66   67   68   69   70   71   72   73   74   75   76