做者 | 高劍林算法
高劍林,騰訊架構平臺部,平臺開發中心基礎研發組組長。前後從事過通信設備的開發和存儲設備的研發工做。目前致力於一體化的涉及—從硬件和軟件的結合,以及OS多個層面綜合考慮系統設計,找出最優路徑的設計思想。編程
以x86體系爲表明的CPU已經佔有了桌面和服務器處理器的絕大部分份額,並且這個趨勢還在不斷加強。CPU具備兼容性強、易編程、應用資源豐富、價格低廉的優點,可是在某些領域,CPU存在自然的缺陷,以FPGA、GPU爲表明的硬件能夠克服CPU的缺陷,所以也擁有本身的市場。緩存
從設計軟件進行計算任務的軟件工程人員的角度,能夠將芯片分爲CPU、GPU、FPGA和ASIC等類型。服務器
對處理器芯片的特性和應用,理論上是軟件人員具備最大發言權。但每一類芯片的使用和理解都不是一件簡單的事情,以CPU爲例:即便從事CPU環境的編程設計多年,也很難談得上深刻理解了CPU的設計思想。能深刻各類芯片編程的軟件人員更是百裏挑一,更別談進行分析和比較。另一個問題是軟件和硬件設計已分離多年,軟件設計人員,很難深刻理解芯片的設計思路,即便操做系統的設計人員也同樣。而芯片的設計廠商因爲利益相關,每每只宣揚各自的優勢,迴避缺陷,在測試對比中選擇有利的測試條件,產生對己有利的測試數據。測試數據的真真假假,更加混淆了技術人員的視聽。網絡
在對各類芯片比較和研究的過程當中,咱們認爲不該該沉湎於具體芯片的架構和設計思路,而應該關注芯片的實際應用。有兩個緣由支持咱們的思路。一個緣由是芯片的架構很是繁複,熟悉各類芯片幾乎是不可能的任務。另外一個更重要的緣由是技術的價值在於應用。無論何種芯片設計或者架構,最終決定芯片價值的是實際的應用。從應用的角度出發,應按照易用性和經濟性兩個維度考察芯片。多線程
易用性指用芯片進行編程的難度以及相關編程資源的獲取難度。這個指標技術人員雖然不怎麼關心,但其實對芯片發展有重大,甚至是絕對的重要性。例如在FPGA的編程實踐中,相關的編程資源很是難以得到,即便得到也每每是代價巨大。好比常見的JPEG圖片,相關的FPGA編解碼庫每每須要付出數萬美圓的成本,這和CPU領域大量的開源庫徹底不能相提並論。價格的昂貴還帶來了測試和驗證的繁雜。提供庫資源的廠商每每須要曠日持久的溝通和談判以及簽署協議才能進行驗證工做,這在不少研發項目運做中幾乎是不可承受的。架構
經濟性指提供相同性能狀況下的芯片成本。芯片每每型號衆多,好比FPGA芯片,既有上千美圓甚至幾千美圓售價的高端型號,也有幾美圓計價的低端型號。脫離芯片成本談論性能沒有意義。須要指出的是,成本是綜合的運營成本,而非單獨的芯片購買成本。好比某款芯片若是性能等於CPU十倍,那麼它不只僅是頂替了十顆CPU,而是頂替了十臺服務器的採購成本以及十臺服務器的運營成本,考慮到實際的運營成本每每大於採購成本,後者可能更具備重要性。併發
對經常使用的處理器芯片進行分類,有一個明顯的特色:CPU&GPU須要軟件支持,而FPGA&ASIC則是軟硬件一體的架構,軟件就是硬件。這個特色是處理器芯片中最重要的一個特徵。性能
上圖能夠從兩個角度來講明:從ASIC->CPU的方向,沿着這個方向芯片的易用性愈來愈強,CPU&GPU的編程須要編譯系統的支持,編譯系統的做用是把高級軟件語言翻譯成機器能夠識別的指令(也叫機器語言)。高級語言帶來了極大的便利性和易用性,所以用CPU&GPU實現同等功能的軟件開發週期要遠低於FPGA&ASIC芯片。沿着CPU->ASIC的方向,芯片中晶體管的效率愈來愈高。由於FPGA&ASIC等芯片實現的算法直接用晶體管門電路實現,比起指令系統,算法直接建築在物理結構之上,沒有中間層次,所以晶體管的效率最高。測試
本質上軟件的操做對象是指令,而CPU&GPU則扮演高速執行指令的角色。指令的存在將程序執行變成了軟件和硬件兩部分,指令的存在也決定了各類處理器芯片的一些徹底不一樣的特色以及各自的優劣勢。
FPGA&ASIC等芯片的功能是固定的,它們實現的算法直接用門電路實現,所以FPGA&ASIC編程就是用門電路實現算法的過程,軟件完成意味着門電路的組織形式已經肯定了,從這個意義上,FPGA&ASIC的軟件就是硬件,軟件就決定了硬件的組織形式。軟硬件一體化的特色決定了FPGA&ASIC設計中極端重要的資源利用率特徵。利用率指用門電路實現算法的過程當中,算法對處理器芯片所擁有的門電路資源的佔用狀況。若是算法比較龐大,可能出現門電路資源不夠用或者雖然電路資源夠用,但實際佈線困難沒法進行的狀況。
存在指令系統的處理器芯片CPU&GPU不存在利用率的狀況。它們執行指令的過程是不斷從存儲器讀入指令,而後由執行器執行。因爲存儲器相對於每條指令所佔用的空間幾乎是無限的,即便算法再龐大也不存在存儲器空間不夠,沒法把算法讀入的狀況。並且計算機系統還能夠外掛硬盤等擴展存儲,經過把暫時不執行的算法切換到硬盤保存更增長了指令存儲的空間。
處理器芯片各自長期發展的過程當中,造成了一些使用和市場上鮮明的特色。CPU&GPU領域存在大量的開源軟件和應用軟件,任何新的技術首先會用CPU實現算法,所以CPU編程的資源豐富並且容易得到,開發成本低而開發週期,而FPGA&ASIC編程須要的資源一般很難得到,這些資源每每以IP(intellectual property)的方式授予和收費,授予的週期每每很長並且須要簽署法律協議,而費用也很昂貴。致使FPGA&ASIC的開發成本高並且週期很長。
不管是x86體系爲表明的繁雜指令系統(CISC)CPU仍是精簡指令系統(RISC)CPU,其核心都是執行一套指令系統。x86體系的CPU不斷更新換代,不斷提高主頻,採用更先進的工藝和新架構,目的就是爲了更高性能地執行x86指令。由於X86系列的CPU應用普遍,已經成爲事實上的標準,本文所指的CPU特指X86系列的CPU。
從CPU內部結構觀察,大體可分爲控制器和執行器,再加上存儲管理部件MMU以及總線接口部件。控制器不斷從存儲器取出指令,進行指令譯碼,執行器從譯碼完成的指令隊列中取出譯碼指令執行。各個功能部件既能獨立工做,又能與其餘部件配合工做,下圖給出了CPU各個部件之間的指令操做流水圖。
指令系統是計算機系統發展中的巨大進步。藉助指令系統,高級語言的出現成爲可能,大大方便了計算機的應用。可是事情的另外一面是使用指令系統後,全部的計算任務都要翻譯爲指令,執行一個簡單的計算任務可能就須要多條指令完成。從晶體管的角度來看,簡單的計算任務可能就須要衆多的晶體管共同參與。爲提高性能,採用指令系統的CPU,其性能設計出發點是加強指令執行的效率。
之前CPU的架構設計一直圍繞如何加強指令執行的效率,爲此採起的措施是不斷提高主頻、加多流水線(奔騰首次應用了雙路流水,而如今的CPU每每擁有20以上的流水數目
)以及增長CPU的cache提高取指令的效率(早期奔騰芯片擁有幾十K的緩存,而至強E5的三級緩存超過10MB,甚至可達到30MB)。近幾年,CPU的架構更加劇視多核的應用,指望經過多核實現更高的性能。
CPU設計出發點是加強指令的運行性能,所以CPU的核心功能強大,佔用的晶體管資源龐大,具備很高的運行效率,所以CPU的多核不可能作到很是多。目前頂級的X86 CPU具備十多個核心,而GPU已經達到幾千個核心。
對編程設計來講,若是線程徹底獨立的執行計算任務,線程間數據不存在共享和競爭關係,那麼並行效率能夠達到線性效果。不過現實中的編程,有很大一類是單任務的並行化,即將一個繁雜的任務經過多核並行執行來加速,那麼就面臨兩個困難:一個是將任務並行化以後面臨多線程之間的切換代價。由於CPU核心功能強大,所以操做系統切換線程時須要CPU內部大量的狀態寄存器置位,因此線程之間切換是代價很大的操做(實測中,線程切換大概須要幾十微秒),若是計算任務的執行時間小於這個數字,那麼多線程執行對性能提高可能並沒有收益,甚至可能效率反而降低。
另外一個問題是任務執行中數據的依賴關係。若是計算任務中某部分必須利用前面部分的計算結果,即存在數據依賴性,那麼就必須等前面部分計算完成才能執行後面的計算,而不可能並行計算。數據依賴是計算中常常遇到的場景,編程設計須要調整代碼結構儘可能減小相關性提高並行性。
GPU(圖形處理器)這個概念最先是顯卡廠商Nvidia公司提出來,如它的名字所象徵的意義,主要是爲圖形處理而設計。圖形處理計算的特徵表現爲高密度的計算而計算須要的數據之間較少存在相關性。下圖展現了GPU和CPU設計的不一樣之處。
圖 CPU架構和GPU對比
如圖所示,GPU的設計出發點在於GPU更適用於計算強度高、多並行的計算。所以,GPU把晶體管更多用於計算單元,而不像CPU用於數據Cache和流程控制器。這樣的設計是由於並行計算時每一個數據單元執行相同程序,不須要繁瑣的流程控制而更須要高計算能力,所以也不須要大的cache容量。
圖 GPU內部結構
如上圖所示,GPU的架構圍繞流處理器(SMX)陣列構建的。 流處理器能同時併發執行上百線程。指令流水線化以利用單線程內的指令級並行,與CPU核不一樣,GPU指令順序發射,沒有分支預測和猜想執行。
流處理器以32個爲一組建立、管理、調度和執行並行線程,這32個線程組稱爲束(warps)。束內包含的不一樣線程從同一程序地址開始,但它們有本身的指令地址計數器和寄存器狀態,所以可自由分支和獨立執行。
束每次執行一個相同的指令,因此若是束內全部32個線程在同一條路徑上執行的話,會達到最高效率。若是因爲數據依賴條件分支致使束分岔,束會順序執行每一個分支路徑,而禁用不在此路徑上的線程,直到全部路徑完成,線程從新匯合到同一執行路徑。分支岔開只會在同一束內發生,不一樣的束獨立執行無論它們是執行相同或不一樣的代碼路徑。
須要注意的是,GPU的線程概念和CPU的線程概念不一樣,CPU有虛存概念,線程具備本身的線程空間和頁表項,還包括CPU的諸多狀態寄存器。所以CPU的線程功能更強大,切換線程的代價也更高,而GPU的線程能夠被看作一些計算指令構成的計算塊,它們的調度、執行和切換要簡單的多。從一個線程的執行上下文切換到另外一個線程的執行上下文沒有消耗,線程之間的切換是硬件切換,消耗的時間幾乎能夠不考慮。
計算任務中可能存在串行的部分。串行指不可並行、必須順序執行的計算部分。這種串行部分極大的下降了任務的並行度和計算性能。在後續的實踐例子中,就遇到了這樣的串行部分。
單獨的GPU缺少必要的環境,沒有外部設備和操做系統的支持,不能和網絡或者本地硬盤交換數據,所以在實際應用中,GPU老是要和CPU搭配使用,共同構成編程的環境,這種編程稱爲異構編程。異構編程不可避免CPU管理的內存和GPU管理的內存之間的數據交互,數據交互的效率極大程度上將影響GPU的運行效率。
FPGA不採用指令和軟件,是軟硬件合一的器件。對FPGA進行編程要使用硬件描述語言,硬件描述語言描述的邏輯能夠直接被編譯爲晶體管電路的組合。因此FPGA實際上直接用晶體管電路實現用戶的算法,沒有經過指令系統的翻譯。
FPGA的英文縮寫名翻譯過來,全稱是現場可編程邏輯門陣列,這個名稱已經揭示了FPGA的功能,它就是一堆邏輯門電路的組合,能夠編程,還能夠重複編程。不能重複編程的FPGA也有,主要是基於反熔絲技術,主要用於軍事用途。下圖展現了可重複編程FPGA的內部原理圖。
圖 FPGA內部結構圖
FPGA內部能夠分爲可配置邏輯模塊CLB、輸入輸出模塊IOB和內部連線等三個部分。IOB是FPGA輸入輸出的接口,提供芯片和外界電路的鏈接,完成不一樣電氣特性對輸入輸出信號的驅動和匹配。
CLB是FPGA的基本邏輯單元。CLB的實際數量根據芯片種類的不一樣而不一樣,以xilinx公司生產的早期FPGA Virtex5系列爲例,每一個CLB包含兩個silce。每一個slice內部包含4個查找表(LUT)、4個觸發器和多路開關等資源。
數字邏輯電路從原理上,是經過時序部件和組合邏輯來完成一系列的功能,而FPGA經過芯片內部衆多的CLB單元提供了衆多的組合邏輯和時序邏輯。所以經過配置CLB就能夠實現各類不一樣的功能。
本文關注的重點不是FPGA的硬件原理,也不是FPGA邏輯設計的技巧和語法,而是從並行計算的角度分析多種芯片和CPU程序設計的特色。
CPU編程和FPGA編程最大的不一樣之處是前者是軟件模式,然後者是硬件模式。軟件模式意味着代碼之間是串行模式,代碼之間有嚴格的執行順序(不考慮指令亂序執行的影響),而硬件模式則意味這代碼之間是並行模式,每一條語句,通過編譯(在硬件領域,編譯被稱爲綜合)以後就是一個真實的邏輯電路。經過一個具體的例子能夠更準確觀察到軟件模式和硬件模式的區別:
對於上面軟件模式的代碼,這兩條語句之間是串行執行的(不考慮指令流水),通過編譯以後,CPU先執行第一條語句,完成a變量的賦值運算,而後執行第二條語句,執行d變量的賦值運算。
若是後續沒有對變量a和d的再次賦值,那麼變量將始終保持當前的賦值不變。
上面語句是FPGA硬件的賦值語句。和CPU軟件模式的執行方式不一樣,上面語句通過綜合後,將造成兩個邏輯電路,一個電路的輸入是b和c,輸出是a,而另外一個電路的輸入是e和f,輸出是d。這二者之間是徹底獨立的,彼此並行而沒有任何的順序關係。
另一點和CPU執行模式不一樣的是,只要輸入端b、c或者e、f有任何的變化,那麼輸出端a或者d也當即變化,不須要再次的賦值。從硬件角度很容易理解這一點,由於FPGA的硬件描述語句被生成爲邏輯電路,它是實實在在的存在而且一直執行,而CPU的指令被執行以後,除非被加載到執行單元再次執行,不然不會自動再執行。
使用FPGA編程,最大的難點在於將原有的串行思路轉變爲並行思路。因爲人腦的思惟模式更接近串行模式,因此用並行模式實現算法和功能的時候,一般困難比串行模式來得大。除此以外,還有以下特性不一樣:
FPGA硬件具備資源佔用率的概念。FPGA編程最終要用邏輯電路實現,所以複雜的算法須要耗用更多的邏輯電路,若是使用的邏輯電路超過芯片的資源是沒法實現的。這個特性和CPU徹底不一樣,CPU的程序存儲在外部存儲中,執行時從外部存儲載入內存執行。內存和外部存儲的容量遠遠超過算法須要的存儲量,基本不可能出現資源不夠用的狀況。
FPGA一般運行的時鐘頻率遠小於CPU的時鐘頻率。對FPGA編程的過程,實際是將芯片內部邏輯電路鏈接起來實現算法和功能的過程。從FPGA的結構能夠發現,FPGA是固定排列的門電路陣列,邏輯電路固定的排列方式決定了編程過程有大量的冗餘電路沒有利用,走線也不可以充分的精簡。所以當前主流FPGA芯片編程一般運行時鐘頻率爲200Mhz~300Mhz,而CPU的運行頻率已超過Ghz的關口,現代主流的X86 CPU的時鐘頻率甚至超過3Ghz。
認識多種處理芯片的特性和實戰GPU&FPGA&ASIC&CPU (下篇)