李逸龍 張 凱 何震瀛 王曉陽(yáng)1,,4
1(復(fù)旦大學(xué)軟件學(xué)院 上海 201203)2(復(fù)旦大學(xué)計(jì)算機(jī)科學(xué)技術(shù)學(xué)院 上海 201203)3(上海市數(shù)據(jù)科學(xué)重點(diǎn)實(shí)驗(yàn)室 上海 200433)4(上海智能電子與系統(tǒng)研究院 上海 201203)
由于物理工藝的限制,近年來CPU的性能已經(jīng)難以得到大幅提升。然而,在大數(shù)據(jù)時(shí)代數(shù)據(jù)量快速增長(zhǎng),這使得CPU越來越難以應(yīng)對(duì)日益增長(zhǎng)的數(shù)據(jù)處理需求。與此同時(shí),利用通用計(jì)算圖形處理器(GPGPU)的并行處理能力來加速計(jì)算任務(wù)成為研究熱點(diǎn)。由于GPU極大地提升了計(jì)算性能,數(shù)據(jù)庫(kù)研究領(lǐng)域也出現(xiàn)了大量用GPU對(duì)查詢計(jì)算任務(wù)進(jìn)行加速的研究。跟傳統(tǒng)的CPU數(shù)據(jù)庫(kù)相比,GPU數(shù)據(jù)庫(kù)在查詢?nèi)蝿?wù)執(zhí)行中展現(xiàn)出非常顯著的加速效果。
利用GPU加速SQL運(yùn)算符的執(zhí)行速度,YDB系統(tǒng)[1]實(shí)現(xiàn)了一個(gè)基于GPU的數(shù)據(jù)庫(kù)系統(tǒng),跟CPU版本的實(shí)現(xiàn)相比,能夠達(dá)到大約2~6倍的查詢速度提升。為了進(jìn)一步提高GPU的資源利用率,出現(xiàn)了以支持并發(fā)查詢?yōu)槟繕?biāo)的研究成果,其中突出的系統(tǒng)有MultiQx-GPU[2]和Ocelot[3]。以MultiQx-GPU系統(tǒng)為例,該系統(tǒng)實(shí)現(xiàn)了并發(fā)查詢之間分時(shí)共享GPU資源的機(jī)制,提升了GPU的資源利用率和系統(tǒng)性能。
然而MultiQx-GPU系統(tǒng)的架構(gòu)設(shè)計(jì)仍然導(dǎo)致了一些問題和缺陷。首先,MultiQx-GPU在每個(gè)查詢?nèi)蝿?wù)進(jìn)程中都需要?jiǎng)?chuàng)建CUDAContext以發(fā)起后續(xù)GPU調(diào)用,耗時(shí)較大。其次,該系統(tǒng)雖然能夠讓并發(fā)的查詢?nèi)蝿?wù)之間分時(shí)共享GPU資源,但是在不同查詢?nèi)蝿?wù)中重復(fù)傳輸了數(shù)據(jù)庫(kù)中相同的列存儲(chǔ)數(shù)據(jù),不但浪費(fèi)了PCIe總線帶寬,還大量占用了GPU資源。以上兩點(diǎn)不足會(huì)造成系統(tǒng)對(duì)GPU整體的資源利用率較低。
針對(duì)以上不足,本文將基于MultiQx-GPU系統(tǒng),提出一種改進(jìn)架構(gòu)的HyperQx-GPU系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)。該系統(tǒng)能夠統(tǒng)一管理GPU硬件資源,減少了每個(gè)查詢?nèi)蝿?wù)單獨(dú)管理GPU的開銷,提升了單個(gè)查詢的執(zhí)行效率。同時(shí),該系統(tǒng)能夠根據(jù)系統(tǒng)中實(shí)時(shí)的查詢?nèi)蝿?wù)運(yùn)行情況,實(shí)現(xiàn)跨并發(fā)查詢?nèi)蝿?wù)的數(shù)據(jù)庫(kù)列存儲(chǔ)數(shù)據(jù)共享,減少系統(tǒng)整體的PCIe數(shù)據(jù)傳輸量,進(jìn)一步提升了系統(tǒng)性能。
系統(tǒng)架構(gòu)方面,該系統(tǒng)采用C/S的架構(gòu)設(shè)計(jì),將數(shù)據(jù)庫(kù)系統(tǒng)分為查詢處理客戶端和數(shù)據(jù)庫(kù)服務(wù)端,兩端用IPC機(jī)制進(jìn)行通信,使得兩個(gè)部分的優(yōu)化可以互不影響地進(jìn)行。跟MultiQx-GPU系統(tǒng)的函數(shù)庫(kù)實(shí)現(xiàn)方式相比,降低了系統(tǒng)組件之間的耦合性,增強(qiáng)了系統(tǒng)功能的可擴(kuò)展性。
實(shí)驗(yàn)結(jié)果證明,本文實(shí)現(xiàn)的HyperQx-GPU系統(tǒng)能夠大大提升GPU的整體資源利用率。對(duì)比MultiQx-GPU系統(tǒng),HyperQx-GPU系統(tǒng)在執(zhí)行并發(fā)SQL查詢的情況下能達(dá)到平均12倍的性能提升。
CPU和GPU的硬件架構(gòu)具有很大差異,具體情況如圖1所示。相比于CPU大量邏輯控制單元和緩存單元的硬件架構(gòu),GPU包含更多計(jì)算核心和高性能內(nèi)存單元,因而更適合被用于處理批量數(shù)據(jù)的密集型并行計(jì)算。以NVIDIAGTX TITAN X型號(hào)GPU為例,該GPU擁有3 584個(gè)計(jì)算核心,并行計(jì)算能力非常強(qiáng)。其還擁有具有5 005 MHz時(shí)鐘頻率和384 bit傳輸位寬的高性能內(nèi)存單元,相比于通常CPU搭配的DDR4內(nèi)存,前者能夠達(dá)到更高的內(nèi)存數(shù)據(jù)訪問速度。
圖1 GPU內(nèi)存數(shù)據(jù)庫(kù)系統(tǒng)架構(gòu)
在目前的GPGPU領(lǐng)域中,最常用的編程框架為OpenCL和CUDA[4]?;诟鶰ultiQx-GPU對(duì)比的目的,本文設(shè)計(jì)的系統(tǒng)實(shí)現(xiàn)過程中采用了CUDA編程框架,因此此處以CUDA為例進(jìn)行介紹。在CUDA編程模型中,程序代碼會(huì)被編譯為CPU運(yùn)行的宿主程序和GPU運(yùn)行的程序,其中GPU中運(yùn)行的函數(shù)被稱為kernel。GPU作為協(xié)處理器,執(zhí)行計(jì)算任務(wù)時(shí)需要CPU上運(yùn)行的宿主程序通過CUDA提供的API進(jìn)行驅(qū)動(dòng),因此其整體上是一個(gè)異構(gòu)的編程模型。
CUDA程序運(yùn)行時(shí),其宿主程序調(diào)用的所有CUDAAPI會(huì)被放到一個(gè)stream內(nèi)。CUDA編程中的一個(gè)stream代表一串連續(xù)的CUDA API調(diào)用命令,同一個(gè)stream內(nèi)的CUDAAPI調(diào)用會(huì)被GPU串行地調(diào)度執(zhí)行。宿主程序可以創(chuàng)建多個(gè)stream,在不同的stream里發(fā)起的命令在沒有數(shù)據(jù)依賴的情況下,會(huì)被GPU調(diào)度器并發(fā)執(zhí)行,從而提升GPU的資源利用率。在CUDA編程中,一個(gè)常用的優(yōu)化手段為利用多個(gè)stream同時(shí)發(fā)起互相不存在依賴關(guān)系的PCIe數(shù)據(jù)傳輸和kernel調(diào)用,使兩者可以同時(shí)執(zhí)行,從而有效利用GPU的數(shù)據(jù)帶寬和計(jì)算資源。
基于GPU的高性能計(jì)算能力,大量研究開始利用GPU加速數(shù)據(jù)庫(kù)的join和sort等SQL操作符[5-8]以及事務(wù)的執(zhí)行[9]。此后,不少研究考慮將GPU作為數(shù)據(jù)庫(kù)查詢執(zhí)行的主要硬件[10-11],如前所述的YDB是典型的設(shè)計(jì)與實(shí)現(xiàn)。相比于CPU數(shù)據(jù)庫(kù)系統(tǒng),YDB系統(tǒng)能顯著地提升查詢?nèi)蝿?wù)執(zhí)行效率。然而其缺點(diǎn)也很明顯,即串行執(zhí)行查詢?nèi)蝿?wù)時(shí),每個(gè)任務(wù)獨(dú)占GPU硬件資源,無法充分利用GPU計(jì)算和PCIe數(shù)據(jù)傳輸帶寬等資源。
為了提升GPU的資源利用率,需要支持并發(fā)的查詢請(qǐng)求。目前支持并發(fā)查詢請(qǐng)求的GPU數(shù)據(jù)庫(kù)系統(tǒng)主要有MultiQx-GPU和Ocelot。以MultiQx-GPU為例,該系統(tǒng)通過動(dòng)態(tài)鏈接庫(kù)攔截的機(jī)制,在執(zhí)行SQL查詢?nèi)蝿?wù)前通過LD_PRELOAD環(huán)境變量預(yù)加載系統(tǒng)提供的動(dòng)態(tài)鏈接庫(kù),攔截了查詢?nèi)蝿?wù)發(fā)起的CUDARuntimeAPI調(diào)用,實(shí)現(xiàn)了并發(fā)的查詢?nèi)蝿?wù)間協(xié)同管理GPU資源的機(jī)制,使得不同任務(wù)進(jìn)程之間可以共享GPU資源。與YDB相比,MultiQx-GPU在執(zhí)行并發(fā)查詢?nèi)蝿?wù)時(shí)能夠達(dá)到平均55%的系統(tǒng)吞吐量提升。MultiQx-GPU的系統(tǒng)架構(gòu)如圖2所示,虛線上方為系統(tǒng)實(shí)現(xiàn)部分,下方為CUDA提供的運(yùn)行時(shí)環(huán)境。
圖2 MultiQx-GPU系統(tǒng)架構(gòu)
盡管MultiQx-GPU系統(tǒng)的設(shè)計(jì)和實(shí)現(xiàn)得到了實(shí)驗(yàn)結(jié)果的驗(yàn)證,但是該系統(tǒng)所達(dá)到的GPU資源利用率仍然還有很大的提升空間。具體而言,其待改進(jìn)之處主要有以下兩點(diǎn):(1) 在不同查詢?nèi)蝿?wù)中重復(fù)傳輸可共享的只讀的數(shù)據(jù)庫(kù)列存儲(chǔ)數(shù)據(jù),造成PCIe總線的帶寬資源浪費(fèi)。圖3展示了HyperQx-GPU系統(tǒng)中(關(guān)閉列存儲(chǔ)數(shù)據(jù)共享功能)一次查詢?nèi)蝿?wù)的執(zhí)行時(shí)間線。從圖中可看出,在334 ms的查詢?nèi)蝿?wù)執(zhí)行時(shí)間中(不包括創(chuàng)建CUDA Context的時(shí)間),CPU內(nèi)存到GPU內(nèi)存的PCIe數(shù)據(jù)傳輸操作占據(jù)了超過75%的時(shí)間(262 ms)。因?yàn)閿?shù)據(jù)庫(kù)中的計(jì)算任務(wù)通常涉及大量的列數(shù)據(jù)掃描和表之間的連接等操作,在執(zhí)行實(shí)際的SQL操作之前需要傳輸大量的列存儲(chǔ)數(shù)據(jù)到GPU內(nèi)存,計(jì)算結(jié)束之后還需要把結(jié)果數(shù)據(jù)從GPU內(nèi)存?zhèn)鬏敾谻PU內(nèi)存。大量的PCIe數(shù)據(jù)傳輸使得本來就稀缺的PCIe總線帶寬成為了該系統(tǒng)執(zhí)行查詢?nèi)蝿?wù)時(shí)的性能瓶頸。(2)MultiQx-GPU系統(tǒng)中的每個(gè)查詢?nèi)蝿?wù)進(jìn)程獨(dú)立調(diào)用CUDARuntimeAPI來使用GPU資源,使得每個(gè)進(jìn)程均需要?jiǎng)?chuàng)建獨(dú)立的CUDAContext,增加查詢?nèi)蝿?wù)的執(zhí)行時(shí)間,進(jìn)而影響系統(tǒng)的整體性能。
圖3 MultiQx-GPU系統(tǒng)PCIe數(shù)據(jù)傳輸時(shí)間線
為了支持高性能的分析型查詢?nèi)蝿?wù),數(shù)據(jù)庫(kù)系統(tǒng)通常采用列存儲(chǔ)的數(shù)據(jù)格式,以減少掃描等查詢操作在單條記錄上的執(zhí)行時(shí)間[11]。比如SQL語(yǔ)句中的where語(yǔ)句,通常會(huì)解析后生成進(jìn)行列掃描的SQL操作,其特點(diǎn)是在某一列的所有數(shù)據(jù)上做同樣的操作,符合向量計(jì)算模型。如果利用GPU的高性能并行計(jì)算能力來執(zhí)行此掃描操作,其執(zhí)行效率能夠得到數(shù)量級(jí)的提升。
HyperQx-GPU系統(tǒng)整體上采用C/S架構(gòu)的設(shè)計(jì)。在查詢?nèi)蝿?wù)端,利用動(dòng)態(tài)鏈接庫(kù)的設(shè)計(jì)達(dá)到系統(tǒng)對(duì)查詢?nèi)蝿?wù)進(jìn)程透明的效果,不會(huì)侵入查詢?nèi)蝿?wù)的代碼邏輯。查詢進(jìn)程通過動(dòng)態(tài)鏈接庫(kù)與數(shù)據(jù)庫(kù)服務(wù)進(jìn)程直接通過IPC機(jī)制通信,保證了具體查詢?nèi)蝿?wù)進(jìn)程和數(shù)據(jù)庫(kù)服務(wù)進(jìn)程之間的低耦合性,使得系統(tǒng)具有良好的可擴(kuò)展性。HyperQx-GPU的系統(tǒng)架構(gòu)如圖4所示。
圖4 HyperQx-GPU系統(tǒng)架構(gòu)
由于CUDA編程框架的異構(gòu)性,HyperQx-GPU系統(tǒng)架構(gòu)從總體上也分為CPU和GPU運(yùn)行的兩部分。其中CPU部分進(jìn)一步分為查詢進(jìn)程和數(shù)據(jù)庫(kù)服務(wù)進(jìn)程;GPU部分主要包括SQL操作符的kernel實(shí)現(xiàn),由數(shù)據(jù)庫(kù)服務(wù)進(jìn)程進(jìn)行加載和調(diào)用。
? 查詢進(jìn)程 查詢進(jìn)程包括兩部分。第一部分由SQL查詢語(yǔ)句請(qǐng)求生成,將解析后的SQL語(yǔ)法樹與數(shù)據(jù)庫(kù)schema結(jié)合起來,編譯成控制數(shù)據(jù)讀取和調(diào)用SQL操作符的CPU宿主程序。該宿主程序負(fù)責(zé)根據(jù)SQL查詢語(yǔ)句邏輯,調(diào)用相應(yīng)的CUDARuntimeAPI控制整個(gè)查詢?nèi)蝿?wù)的邏輯流程。第二部分為與數(shù)據(jù)庫(kù)服務(wù)進(jìn)程進(jìn)行IPC通信的客戶端動(dòng)態(tài)鏈接庫(kù),利用動(dòng)態(tài)鏈接庫(kù)攔截技術(shù)攔截了到CUDA動(dòng)態(tài)鏈接庫(kù)libcudart的調(diào)用,將CPU宿主程序中包含的CUDARuntimeAPI調(diào)用映射為到服務(wù)進(jìn)程的IPC調(diào)用。
?服務(wù)進(jìn)程 數(shù)據(jù)庫(kù)服務(wù)進(jìn)程通過監(jiān)聽Unix Domain Socket來接收查詢?nèi)蝿?wù)端通過動(dòng)態(tài)鏈接庫(kù)發(fā)起的IPC請(qǐng)求,調(diào)用數(shù)據(jù)庫(kù)管理層的函數(shù)進(jìn)行實(shí)際的GPU查詢?nèi)蝿?wù)執(zhí)行和資源調(diào)度等任務(wù),并將結(jié)果返回給查詢?nèi)蝿?wù)客戶端。數(shù)據(jù)庫(kù)的核心管理層包含列存儲(chǔ)數(shù)據(jù)共享、GPU硬件管理和kernel調(diào)用等核心服務(wù)的邏輯,以函數(shù)庫(kù)的形式向服務(wù)進(jìn)程提供數(shù)據(jù)庫(kù)管理功能。
服務(wù)進(jìn)程采用多線程的架構(gòu),使用獨(dú)立的線程來服務(wù)不同查詢?nèi)蝿?wù)進(jìn)程的請(qǐng)求,以降低不同任務(wù)的相互影響,同時(shí)可以方便地支持并發(fā)查詢,具有很好的可伸縮性。并且,使用多線程架構(gòu)使得某一個(gè)任務(wù)的失敗不會(huì)影響到系統(tǒng)中正在執(zhí)行的其他任務(wù),起到了查詢?nèi)蝿?wù)隔離效果,同時(shí)系統(tǒng)的整體邏輯也更加清晰。
本節(jié)將詳細(xì)介紹HyperQx-GPU系統(tǒng)中兩個(gè)核心功能——共享CUDAContext和共享數(shù)據(jù)庫(kù)列存儲(chǔ)數(shù)據(jù)的設(shè)計(jì)與實(shí)現(xiàn),并闡述該實(shí)現(xiàn)方式的優(yōu)勢(shì)。
2.2.1 共享CUDAContext
在數(shù)據(jù)庫(kù)系統(tǒng)運(yùn)行的所有查詢?nèi)蝿?wù)間共享服務(wù)進(jìn)程中的CUDAContext,用于發(fā)起所有的GPU調(diào)用,是HyperQx-GPU系統(tǒng)的核心設(shè)計(jì)之一。該設(shè)計(jì)使得查詢?nèi)蝿?wù)的CUDARuntimeAPI調(diào)用能夠被數(shù)據(jù)庫(kù)服務(wù)進(jìn)程統(tǒng)一管理,節(jié)省了每個(gè)查詢?nèi)蝿?wù)進(jìn)程需要單獨(dú)創(chuàng)建CUDAContext的開銷,提高了GPU的整體資源利用率。
HyperQx-GPU服務(wù)端進(jìn)程初始化時(shí)會(huì)創(chuàng)建一個(gè)CUDA Context,作為整個(gè)數(shù)據(jù)庫(kù)系統(tǒng)生命周期中,調(diào)度GPU資源的全局唯一環(huán)境。當(dāng)查詢?nèi)蝿?wù)啟動(dòng)時(shí),由于其CUDA Runtime API調(diào)用被動(dòng)態(tài)鏈接庫(kù)攔截,并不會(huì)觸發(fā)CUDA隱式創(chuàng)建CUDA Context的機(jī)制,而是通過數(shù)據(jù)庫(kù)服務(wù)進(jìn)程使用全局唯一的CUDA Context,節(jié)省了每個(gè)查詢進(jìn)程單獨(dú)創(chuàng)建所消耗的時(shí)間。
為了使每個(gè)查詢?nèi)蝿?wù)進(jìn)程之間的CUDARuntime-API調(diào)用互不阻塞,服務(wù)進(jìn)程在啟動(dòng)每個(gè)查詢服務(wù)線程時(shí),會(huì)在CUDAContext中創(chuàng)建一個(gè)單獨(dú)的stream,用于發(fā)起該查詢進(jìn)程請(qǐng)求的GPU調(diào)用。不同stream上進(jìn)行的CUDAAPI調(diào)用不會(huì)相互阻塞,會(huì)被GPU并發(fā)調(diào)度執(zhí)行,因此可以同時(shí)進(jìn)行不同查詢?nèi)蝿?wù)的PCIe數(shù)據(jù)傳輸和kernel調(diào)用,充分利用GPU資源。
2.2.2 共享列存儲(chǔ)數(shù)據(jù)
HyperQx-GPU系統(tǒng)的另一個(gè)核心設(shè)計(jì)是實(shí)現(xiàn)了跨查詢?nèi)蝿?wù)的列存儲(chǔ)數(shù)據(jù)共享機(jī)制:多個(gè)查詢?nèi)蝿?wù)如果使用了相同的列存儲(chǔ)數(shù)據(jù),服務(wù)進(jìn)程會(huì)根據(jù)當(dāng)前的系統(tǒng)狀態(tài)決定通過PCIe總線傳輸數(shù)據(jù)到GPU內(nèi)存或者復(fù)用已經(jīng)存在于GPU內(nèi)存的數(shù)據(jù)。下面將詳細(xì)介紹該機(jī)制的行為和實(shí)現(xiàn)。
服務(wù)進(jìn)程在初始化時(shí),會(huì)將數(shù)據(jù)庫(kù)的列存儲(chǔ)數(shù)據(jù)預(yù)加載到內(nèi)存,并生成數(shù)據(jù)表中列的名稱到內(nèi)存地址空間的映射表。當(dāng)查詢?nèi)蝿?wù)進(jìn)程需要訪問特定列的數(shù)據(jù)時(shí),會(huì)通過客戶端動(dòng)態(tài)鏈接庫(kù)進(jìn)行IPC請(qǐng)求,服務(wù)進(jìn)程則根據(jù)請(qǐng)求中的數(shù)據(jù)表名和列名,返回該列對(duì)應(yīng)的內(nèi)存地址作為后續(xù)操作的句柄。由于列存儲(chǔ)數(shù)據(jù)只存在于服務(wù)進(jìn)程的內(nèi)存地址空間,因此查詢?nèi)蝿?wù)進(jìn)程無法通過該地址直接訪問或修改數(shù)據(jù)庫(kù)的列存儲(chǔ)數(shù)據(jù),起到了隔離效果。
當(dāng)查詢?nèi)蝿?wù)發(fā)起列存儲(chǔ)數(shù)據(jù)從CPU內(nèi)存到GPU內(nèi)存的傳輸請(qǐng)求時(shí),服務(wù)進(jìn)程會(huì)查看當(dāng)前映射表中該列的使用情況。若該列尚未被使用過,則分配相應(yīng)的GPU內(nèi)存空間,將該列存儲(chǔ)數(shù)據(jù)通過PCIe總線傳輸?shù)紾PU內(nèi)存,然后將映射表中該列的使用進(jìn)程數(shù)設(shè)置為1,并返回GPU內(nèi)存地址給查詢?nèi)蝿?wù)進(jìn)程。若該列存儲(chǔ)數(shù)據(jù)已經(jīng)存在于GPU內(nèi)存中,這時(shí)候?qū)⒂成浔碇性摿械氖褂眠M(jìn)程數(shù)加1,然后直接返回該列存儲(chǔ)數(shù)據(jù)的GPU地址。該查詢?nèi)蝿?wù)中,后續(xù)對(duì)該列的使用便可以直接使用已經(jīng)存在于GPU內(nèi)存的列存儲(chǔ)數(shù)據(jù),達(dá)到了共享列存儲(chǔ)數(shù)據(jù)的目的,節(jié)省了PCIe傳輸開銷。當(dāng)查詢?nèi)蝿?wù)結(jié)束時(shí),服務(wù)進(jìn)程會(huì)從列存儲(chǔ)數(shù)據(jù)映射表中將該查詢?nèi)蝿?wù)用到的所有列存儲(chǔ)數(shù)據(jù)減去1。極端情況下,當(dāng)GPU內(nèi)存空間不足時(shí),若某個(gè)列存儲(chǔ)數(shù)據(jù)的使用進(jìn)程數(shù)為0,則該列存儲(chǔ)數(shù)據(jù)占用GPU內(nèi)存空間可以被暫時(shí)釋放,之后再次使用時(shí)再重新傳輸?shù)紾PU內(nèi)存。
通過上述的列存儲(chǔ)數(shù)據(jù)共享機(jī)制,HyperQx-GPU系統(tǒng)節(jié)省了每個(gè)查詢?nèi)蝿?wù)需要進(jìn)行的列存儲(chǔ)數(shù)據(jù)的PCIe傳輸,提升了系統(tǒng)的整體性能。
本節(jié)以一個(gè)具體的SQL查詢?yōu)槔?,詳?xì)描述HyperQx-GPU系統(tǒng)處理查詢請(qǐng)求的主要執(zhí)行流程,從而展示系統(tǒng)各個(gè)功能模塊之間的關(guān)系和交互行為。如下流程描述中,編號(hào)由小到大表示時(shí)間順序。
(1) 啟動(dòng)數(shù)據(jù)庫(kù)系統(tǒng)服務(wù)進(jìn)程,該進(jìn)程會(huì)創(chuàng)建CUDA Context,并根據(jù)啟動(dòng)參數(shù)datadir,修改文件夾預(yù)加載列存儲(chǔ)數(shù)據(jù)到系統(tǒng)內(nèi)存,然后監(jiān)聽查詢請(qǐng)求。(2) 用戶向數(shù)據(jù)庫(kù)系統(tǒng)提交了如下的SQL查詢語(yǔ)句:SELECTSUM(lo_extendprice*lo_discount) AS revenue FROM lineorder,ddate WHERE lo_orderdate=d_datekey AND d_year=1993 AND lo_discount>=1 AND lo_discount<=3 AND lo_quantity<25。(3) 數(shù)據(jù)庫(kù)查詢前端模塊先將SQL字符串解析成SQL語(yǔ)法樹,然后結(jié)合數(shù)據(jù)庫(kù)表的schema生成包含SQL操作符對(duì)應(yīng)kernel調(diào)用的CPU宿主程序代碼,代表查詢?nèi)蝿?wù)的實(shí)際邏輯——在本例中會(huì)生成列掃描過濾和表之間的哈希連接等kernel調(diào)用。由SQL生成的代碼被編譯成可執(zhí)行文件后,將LD_PRELOAD環(huán)境變量設(shè)置為數(shù)據(jù)庫(kù)客戶端動(dòng)態(tài)鏈接庫(kù)的路徑,然后執(zhí)行該文件,啟動(dòng)查詢?nèi)蝿?wù)進(jìn)程。(4) 查詢?nèi)蝿?wù)進(jìn)程發(fā)起的CUDARuntimeAPI調(diào)用被客戶端動(dòng)態(tài)鏈接庫(kù)攔截,轉(zhuǎn)化成到服務(wù)進(jìn)程的IPC請(qǐng)求。(5) 服務(wù)端接收到新的查詢?nèi)蝿?wù)進(jìn)程的IPC請(qǐng)求后,創(chuàng)建新的服務(wù)線程處理來自該進(jìn)程的后續(xù)請(qǐng)求。該服務(wù)線程會(huì)不斷解析來自同一個(gè)查詢?nèi)蝿?wù)進(jìn)程的請(qǐng)求消息體,通過數(shù)據(jù)庫(kù)核心管理層模塊執(zhí)行相應(yīng)的資源管理和kernel調(diào)用等操作,并將結(jié)果通過IPC機(jī)制回傳給查詢?nèi)蝿?wù)進(jìn)程。在本示例查詢中,服務(wù)進(jìn)程會(huì)保證kernel執(zhí)行前,lineorder表中用到的4列數(shù)據(jù)和ddate表中的2列數(shù)據(jù)已經(jīng)被傳輸?shù)搅薌PU內(nèi)存。如果同時(shí)發(fā)起該SQL語(yǔ)句的兩個(gè)查詢請(qǐng)求實(shí)例,后到的請(qǐng)求會(huì)復(fù)用前一個(gè)請(qǐng)求已經(jīng)傳輸?shù)紾PU的列存儲(chǔ)數(shù)據(jù),而不進(jìn)行實(shí)際的PCIe數(shù)據(jù)傳輸。(6) 查詢結(jié)果(包括查詢中產(chǎn)生的宿主程序需要的臨時(shí)結(jié)果)會(huì)通過IPC回傳給動(dòng)態(tài)鏈接庫(kù),進(jìn)而返回給查詢?nèi)蝿?wù)進(jìn)程。(7) 查詢進(jìn)程完成查詢時(shí),向服務(wù)進(jìn)程發(fā)起退出請(qǐng)求,服務(wù)進(jìn)程結(jié)束相應(yīng)的服務(wù)線程。
實(shí)驗(yàn)所用工作站搭載開啟Hyper-threading的18核2.1 GHz Intel XeonE5-2695 CPU,和32 GB DRAM系統(tǒng)內(nèi)存。實(shí)驗(yàn)使用的GPU為NVIDIA TITAN X,包含12 GB內(nèi)存,以及3 584個(gè)時(shí)鐘頻率為1 531 MHz的計(jì)算核心。該系統(tǒng)的SQL操作符kernel代碼和其余模塊代碼使用NVIDIACUDA Toolkit 9.0和GCC 6.1.0工具鏈進(jìn)行編譯。工作站運(yùn)行的操作系統(tǒng)為CentOS Linux release 7.4.1708,Linux內(nèi)核版本為3.10.0。
本實(shí)驗(yàn)使用的數(shù)據(jù)集為MultiQx-GPU采用的標(biāo)準(zhǔn)測(cè)試基準(zhǔn)數(shù)據(jù)SSB(Star Schema Benchmark)[12],其中包括13條SQL查詢語(yǔ)句和生成的數(shù)據(jù)庫(kù)數(shù)據(jù)。該數(shù)據(jù)集基于TPC-H測(cè)試基準(zhǔn)并加以修改,在數(shù)據(jù)庫(kù)相關(guān)研究中被廣泛運(yùn)用于測(cè)試實(shí)際查詢負(fù)荷狀態(tài)下的數(shù)據(jù)庫(kù)系統(tǒng)性能。實(shí)驗(yàn)使用的數(shù)據(jù)庫(kù)數(shù)據(jù)由SSB的數(shù)據(jù)生成工具dbgen生成,并預(yù)處理成MultiQx-GPU中使用的列存儲(chǔ)格式,即每個(gè)表的每個(gè)列會(huì)被單獨(dú)存儲(chǔ)為一個(gè)文件。若表中包含記錄數(shù)過多,每個(gè)列存儲(chǔ)文件會(huì)包含多個(gè)數(shù)據(jù)塊,最終被系統(tǒng)分批載入GPU處理。生成數(shù)據(jù)時(shí),使用10作為規(guī)模放大參數(shù)(scalefactor),最終生成的數(shù)據(jù)表中大約包含6千萬(wàn)條記錄,占用磁盤空間為4.8 GB。實(shí)驗(yàn)使用的查詢?nèi)蝿?wù)共由13條SQL查詢語(yǔ)句組成。由于實(shí)驗(yàn)?zāi)康氖菧y(cè)試系統(tǒng)的核心模塊性能,為了排除SQL語(yǔ)句的解析和編譯時(shí)間,所有SQL查詢語(yǔ)句均被預(yù)先編譯成可執(zhí)行的查詢?nèi)蝿?wù)程序。實(shí)驗(yàn)開始時(shí),所有列數(shù)據(jù)均被預(yù)先加載入內(nèi)存,以避免查詢過程中產(chǎn)生不必要的磁盤到內(nèi)存的數(shù)據(jù)傳輸。同時(shí),實(shí)驗(yàn)設(shè)定所有列存儲(chǔ)數(shù)據(jù)和查詢?nèi)蝿?wù)執(zhí)行時(shí)產(chǎn)生的中間結(jié)果均能在GPU內(nèi)存中同時(shí)存在而不超出內(nèi)存空間總量。
實(shí)驗(yàn)主要測(cè)試內(nèi)容為驗(yàn)證共享CUDAContext和共享列存儲(chǔ)數(shù)據(jù)機(jī)制帶來的系統(tǒng)性能提升。參照MultiQx-GPU,本實(shí)驗(yàn)所采用的吞吐量指標(biāo)為加權(quán)吞吐量,定義如下:
本實(shí)驗(yàn)使用MultiQx-GPU系統(tǒng)性能作為基準(zhǔn),采用查詢?nèi)蝿?wù)兩兩并發(fā)(包括兩個(gè)相同查詢?nèi)蝿?wù)并發(fā)的情況)的方式,測(cè)試HyperQx-GPU系統(tǒng)在共91個(gè)(互不相同并發(fā)查詢組合78個(gè),相同并發(fā)查詢組合13個(gè))查詢?nèi)蝿?wù)組合并發(fā)執(zhí)行情況下的相對(duì)吞吐量。由于單獨(dú)執(zhí)行一個(gè)查詢所用時(shí)間較短,且啟動(dòng)進(jìn)程等操作會(huì)給系統(tǒng)帶來開銷,有可能在第一個(gè)查詢?nèi)蝿?wù)快結(jié)束時(shí),第二個(gè)查詢?nèi)蝿?wù)才開始執(zhí)行。為了保證實(shí)驗(yàn)進(jìn)行時(shí)每組中的兩個(gè)查詢能同時(shí)執(zhí)行,本實(shí)驗(yàn)實(shí)在兩個(gè)進(jìn)程中重復(fù)串行地執(zhí)行兩個(gè)查詢?nèi)蝿?wù),以一次查詢?nèi)蝿?wù)執(zhí)行時(shí)間內(nèi)的平均相對(duì)吞吐量作為最終的實(shí)驗(yàn)結(jié)果。實(shí)驗(yàn)結(jié)果數(shù)據(jù)如圖5和圖6所示。
圖5 HyperQx-GPU相對(duì)吞吐量提升
圖6 HyperQx-GPU相對(duì)吞吐量提升
從圖5和圖6所示的實(shí)驗(yàn)數(shù)據(jù)可以看出,在HyperQx-GPU系統(tǒng)的新架構(gòu)下,系統(tǒng)在查詢?nèi)蝿?wù)兩兩并發(fā)執(zhí)行的情況下,其查詢請(qǐng)求處理的相對(duì)吞吐量平均達(dá)到了MultiQx-GPU系統(tǒng)的12.0倍。其中最低的查詢組合為q7和q7并發(fā)執(zhí)行,相對(duì)吞吐量達(dá)到4.5倍,而最高的查詢組合為q10和q10并發(fā)執(zhí)行,其相對(duì)吞吐量能達(dá)到19.0倍。本相對(duì)吞吐量測(cè)量結(jié)果表明,與MultiQx-GPU系統(tǒng)相比,HyperQx-GPU系統(tǒng)的性能提升非常明顯。
為了進(jìn)一步驗(yàn)證導(dǎo)致HyperQx-GPU系統(tǒng)性能提升的獨(dú)立因素,下列兩組實(shí)驗(yàn)將進(jìn)一步驗(yàn)證和分析共享CUDAContext和共享列存儲(chǔ)數(shù)據(jù)兩項(xiàng)改進(jìn)技術(shù)分別帶來的系統(tǒng)吞吐量提升效果。
在MultiQx-GPU系統(tǒng)架構(gòu)設(shè)計(jì)中,每個(gè)查詢?nèi)蝿?wù)進(jìn)程使用CUDARuntimeAPI控制查詢邏輯時(shí),會(huì)在第一次調(diào)用RuntimeAPI的時(shí)候隱式地創(chuàng)建CUDAContext。本實(shí)驗(yàn)測(cè)試MultiQx-GPU和HyperQx-GPU系統(tǒng)(關(guān)閉列存儲(chǔ)共享功能)執(zhí)行單個(gè)查詢?nèi)蝿?wù)的時(shí)間。實(shí)驗(yàn)數(shù)據(jù)如圖7所示。
圖7 MultiQx-GPU和HyperQx-GPU關(guān)閉共享列數(shù)據(jù)對(duì)比
根據(jù)實(shí)驗(yàn)數(shù)據(jù),HyperQx-GPU利用共享CUDA Context機(jī)制,與MultiQx-GPU相比,平均性能提升(減少執(zhí)行時(shí)間)為75.0%。其中提升最多的為q3查詢,減少執(zhí)行時(shí)間為79.6%;最低為q11查詢,減少執(zhí)行時(shí)間為68.5%。因此,在服務(wù)進(jìn)程中使用全局唯一的CUDAContext進(jìn)行GPU資源調(diào)度,能夠節(jié)省在每個(gè)查詢進(jìn)程啟動(dòng)時(shí)的CUDA Context創(chuàng)建開銷,使GPU更多地處于執(zhí)行計(jì)算任務(wù)的狀態(tài),從而提升系統(tǒng)的查詢請(qǐng)求響應(yīng)速度和吞吐量。
為了驗(yàn)證共享列存儲(chǔ)技術(shù)帶來的系統(tǒng)相對(duì)吞吐量的提升效果,本實(shí)驗(yàn)測(cè)試了全部的13個(gè)SQL查詢語(yǔ)句在HyperQx-GPU系統(tǒng)中分別在開啟和關(guān)閉列存儲(chǔ)數(shù)據(jù)共享功能情況下,查詢?nèi)蝿?wù)在PCIe總線數(shù)據(jù)傳輸過程上花費(fèi)的時(shí)間。本實(shí)驗(yàn)采用串行(非并發(fā))的查詢執(zhí)行情況,以排除其他因素對(duì)系統(tǒng)性能的影響。實(shí)驗(yàn)結(jié)果如圖8所示。
圖8 HyperQx-GPU共享與不共享列存儲(chǔ)數(shù)據(jù)情況下PCIe總線數(shù)據(jù)傳輸時(shí)間對(duì)比
從實(shí)驗(yàn)結(jié)果數(shù)據(jù)中可以看出,支持列存儲(chǔ)數(shù)據(jù)共享機(jī)制的HyperQx-GPU系統(tǒng)能夠大幅地減少PCIe數(shù)據(jù)傳輸消耗的時(shí)間。其中減少時(shí)間最多的查詢?yōu)閝2,減少了98.2%;減少時(shí)間最少的查詢?yōu)閝4,減少了96.4%,平均減少的PCIe數(shù)據(jù)傳輸消耗時(shí)間為97.2%。實(shí)際執(zhí)行查詢?nèi)蝿?wù)時(shí),HyperQx-GPU系統(tǒng)能夠根據(jù)系統(tǒng)中實(shí)時(shí)運(yùn)行的所有查詢?nèi)蝿?wù)的信息,重復(fù)利用已經(jīng)傳輸過的數(shù)據(jù)庫(kù)列存儲(chǔ)數(shù)據(jù),從而提升系統(tǒng)吞吐量。該實(shí)驗(yàn)證明,共享列存儲(chǔ)數(shù)據(jù)的機(jī)制幾乎能夠消除查詢?nèi)蝿?wù)執(zhí)行時(shí)的PCIe數(shù)據(jù)傳輸瓶頸,為進(jìn)一步的系統(tǒng)優(yōu)化提供了有力支持。
本文發(fā)現(xiàn)并分析了已有GPU數(shù)據(jù)庫(kù)系統(tǒng)均存在的GPU整體資源利用率低的缺陷。在此基礎(chǔ)上,本文提出并實(shí)現(xiàn)了HyperQx-GPU系統(tǒng)。該系統(tǒng)設(shè)計(jì)并實(shí)現(xiàn)了新的軟件架構(gòu),通過共享CUDAContext節(jié)省了查詢?nèi)蝿?wù)執(zhí)行時(shí)間,使用共享列存儲(chǔ)數(shù)據(jù)方案減少了查詢?nèi)蝿?wù)中的PCIe數(shù)據(jù)傳輸量,優(yōu)化了GPU資源利用率。本文通過實(shí)驗(yàn)測(cè)試,分析了以上兩個(gè)關(guān)鍵技術(shù)分別帶來的系統(tǒng)性能提升。實(shí)驗(yàn)結(jié)果表明,HyperQx-GPU系統(tǒng)在MultiQx-GPU系統(tǒng)的基礎(chǔ)上,提升GPU數(shù)據(jù)庫(kù)處理并發(fā)查詢請(qǐng)求的平均相對(duì)吞吐量達(dá)到了12.0倍。