中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Python編寫EVE的具體思路

發布時間:2020-06-29 09:35:06 來源:億速云 閱讀:329 作者:清晨 欄目:編程語言

小編給大家分享一下Python編寫EVE的具體思路,希望大家閱讀完這篇文章后大所收獲,下面讓我們一起去探討方法吧!

大多數熟悉EVE的人都知道,它是用Python語言編寫的,如果要說得更具體點,那就是Stackless Python。Stackless是在Python基礎上編寫的一套微線程框架,它能在不產生大量Python自身額外開銷的情況下同時容納數百萬條的線程。

但話還是要說回來,它畢竟還是Python,因此擺脫不了“解釋器全局鎖”(Global Interpreter Lock,下文將其簡稱為GIL)。

GIL是一個序列鎖,用來保證在任何時候都只能有一個線程利用Python解釋器(包括其所有數據)來運行自己。因此,盡管Stackless Python感覺上好像具備多線程處理能力,但實際上它還是單線程的,只不過運用了任務分離、頻道、定時器及共享內存等一系列招數而已。

其實過去有些協作式的多任務操作系統也是這樣干的,其好處是保證了所有線程都能被執行,不會出現被操作系統提前結束這一情況(除非被操作系統懷疑非法宕機)。GIL的存在使得程序員在編寫游戲邏輯時能自信推斷出程序的全局狀態,省去了一大堆采用異步回調函數的麻煩。

但這樣有一大缺點:由于EVE中有部分框架的代碼是用Python編寫的,因此它們都免不了GIL造成的負面影響。比如,一段用來讀取Python數據的C++語言代碼必須在獲得GIL后才能讀取一個字符串。

Python編寫EVE的具體思路

使用Python的任務都要獲得GIL才能合法地被處理,這樣等同于Python任務都是單線程執行。

(這圖畫得不太好看,人家只是個程序員,不是美術師哦)

一言以蔽之,Stackless Python 代碼的運行速度不會高于你最快的那個CPU核心的速度。在一臺4核或8核CPU的服務器上,其中只有一核在超負荷運作,其他都沒派上用場。當然,為了讓這些CPU核心物盡其用,我們可以在它們身上加載更多的節點。

對于EVE中許多無狀態或對共享狀態依賴度極低的代碼而言,這沒什么問題。但對于像太空模擬或空間站行走這樣高度依賴共享狀態的代碼而言,就成了一個大問題。

假設一個CPU核心就能處理所有的邏輯并且寫出來的Python代碼較為清晰,那我之前說的都不是什么問題。不過,想必我不用說大家也知道,盡管Gridlock等小組已經在優化工作方面做到了其極致,但我們現在面臨的情況依舊是單個CPU已經無法處理一場大型會戰了。

最近上市的CPU速度是更快、緩存容量也更大、總線也更寬裕并且具備更好的執行流水線,但在EVE需要其給力的地方,卻沒有任何進步。近期(也可能包括中長期)的趨勢是“橫向增長”,即同時運行多個CPU核心。

總體而言,多核CPU的流行對EVE的長遠發展是一大利好。未來那些30乃至60核CPU的機器能夠很好地體現EVE集群部署方式的優勢,這是因為CPU核心之間切換的效率將遠遠大于線程之間切換的效率。

但就目前而言,為了提升游戲運行速度,我們需要把網絡及通用讀寫這樣的EVE模塊從GIL中解放出來。

多核心、超標量的硬件對當今的網絡游戲來說,都是個好消息。這些游戲很適合這種架構,并且能很容易地進行并行處理。可惜對于依賴Python的EVE來說,這就算不得好消息了。

那些對運行速度要求極高、不需要Python便利開發優勢的EVE系統需要盡早擺脫GIL的束縛。CarbonIO在這個方向上可以說是向前邁進了一大步。

CarbonIO 是在StacklessIO 基礎上的一個自然提升。它實際上是個從頭寫起的全新引擎,目標非常明確:讓網絡流量擺脫GIL的束縛,并且讓任何C++代碼也能這樣做。后半個目的是重頭戲,我們花了大半年才把它完成。

這里不得不先稍微提一下StacklessIO。對Stackless Python的網絡通信而言,它可以說是個質的飛躍。通過讓網絡操作變得具有“無堆棧的意識”,StacklessIO可以將一個被鎖住的操作轉移到一個未被GIL鎖住的線程上,這樣該操作就可以繼續等候,而Stackless則繼續處理其他事務。

然后,該操作重新獲得GIL,告訴Stackless其操作已完成。這樣,接收端就可以同步進行,使得通訊速度可以達到操作系統級別,并且能基本上在第一時間內回報給Python。

Python編寫EVE的具體思路

StacklessIO在沒有GIL的情況下完成Python請求

CarbonIO在此基礎上更上一層樓。由于它是在完全脫離于GIL的情況下運行多線程通信引擎,因此Python與該系統之間的交互便是完全獨立了。沒有Python的要求,它也能收發數據。

請允許我再強調一下:CarbonIO能在Python不作任何要求的情況下收發數據。這是并發性的,不需要GIL。

當一個連接通過CarbonIO被建立后,系統會調用WSARecv()開始接收數據。與Python進程并行的線程池將這些數據解密、解壓縮然后轉義到數據包里。這些數據包會排隊,等著Python來處理。

當Python覺得它需要一個數據包時,它會往下調用“可能已將此包準備就緒”的CarbonIO。這意味著數據在離開隊列被返回整個過程中根本沒有用到GIL。這是一個瞬時過程,至少也有納秒那么快。這個并行讀取能力是CarbonIO的第一大好處。

第二大好處便是發送了。數據以其原始形式排在工作線程隊列里,然后便等著Python來調用了。

其間的壓縮、加密、打包及WSASend()調用都沒有觸及GIL而發生在另一個線程里,這樣操作系統便可以安排它運行在另一顆CPU上了。C++代碼也可以調用一個方法來這樣做,并不需要特別的架構變更。StacklessIO也可以那樣做,但在脫離上述背景的情況下,這會變得很沒意義。

讓我們再來回顧一下之前提到的“已將此包準備就緒”。但如果我們要安置一個C++回調鉤子函數,使得非Python模塊能在不觸及Machonet的情況下獲得那個數據,這可行嗎?行啊,這時我們要用的就是BlueNet了。

Python編寫EVE的具體思路

CarbonIO不停地進行數據接收,并且能在無Python介入的情況下告訴C++模塊數據已收到。

Machonet是一個大型功能集合,它負責對會話進行分流、導向及管理,負責對數據包的時間計劃/發送以及其他一系列將EVE撮合成一個有機整體的功能。

由于它是個Python模塊,因此所有的數據遲早都必須觸及那倒霉的GIL,無論數據在哪個節點。無論一個C++模塊的速度有多快,GIL仍然是個繞不過的瓶頸。這使得我們曾經都不太愿意做大量的C++優化,因為任何優化后取得的優勢都會被Machonet 中的GIL吞噬。

但現在情況不一樣了。

現在C++的系統能通過BlueNet收發數據包,無需再理會GIL。這原來是專門為了空間站行走設計的。空間站行走功能需要發送大量的表示移動的數據。

EVE中太空飛行的那部分功能所需要收發的數據,我們以前可以用旁門左道的方法來解決,但對于如此近距離的人物動作,就不行了。之前我們做的預測顯示,即使把空間站行走發送數據的頻率控制在一般程度,該功能也會把整個服務器集群拖垮。

通過在沒有GIL干擾的情況下對流入/流出C++原生系統(比如物理系統)的數據進行分流,BlueNet成功地解決了該問題。由于在這種情況下,數據還是保持著其原生態,因此整個系統運行的速度就比之前提高了。

這個具體是怎么運作的呢?BlueNet保存著一份所有必要Machonet結構的只讀拷貝,另外,所有的數據包前都會附上很小的一段(8到10個字節的)數據頭。這個數據頭里含有路徑信息。

當BlueNet接到一個數據包時,它會對其進行檢測,然后合理地再分發:要么轉發到另一個節點上,要么交給被本地的已注冊的C++應用程序。如果它轉發,那這個過程中將用不到GIL,根本不會調用Machonet/Python。

這意味著我們的代理服務器完全能以并行方式對BlueNet的數據包進行分流,而不必去經過Python導致額外開銷的產生。那這效率究竟提高了多少呢?我們還無法確定,但在降低機器負載及延遲方面,它還是非常非常明顯的。實際上我們還不能將數據公開,因為它們好得難以置信。

除此之外,CarbonIO也包含了大量底層優化,絕大多數都是小規模的速度提升,但把這些統統疊加起來,整個系統的運行速度也就有了顯著提高。以下幾點值得一提:

工作分組

雖然我很難在本文中把這事兒說得太細,但CarbonIO非常出色地將工作分組來處理。

簡而言之,就是某些操作有了一個固定的開銷。網絡引擎有許多這樣的開銷,但其他所有具有重要意義的代碼也有大量開銷。通過一些別出心裁的技巧,我們是可以將許多這樣的工作合并在一起,這樣就只產生一次開銷。

就像把邏輯數據包都組合在一起發送在一個TCP/IP MTU里一樣(EVE一直就是這樣干的),CarbonIO將這一做法進一步深化。一個比較簡單的例子就是GIL獲取集合。

第一個要嘗試取得GIL的線程會先建立起一個隊列,這樣其他要獲取GIL的線程只需將自己的喚醒調用排在隊列末尾然后返回線程池就行。那GIL最后被取得時,第一個線程會吸干整個隊列,不必在每次IO喚醒時釋放/重拾GIL。

在一個繁忙的服務器上這種情況很多,因此這種改進對我們來說是一大利好。

openSSL 整合

CarbonIO用openSSL來實現SSL,并且能在不鎖定GIL的情況下與該協議數據通信。該庫只是用作一個BIO對而已,所有的數據導航還是由CarbonIO通過完成端口進行的。

這有助于我們循序漸進地讓EVE變得更安全,甚至將來可以把官方網站上的某些帳號管理功能挪到EVE客戶端上去,這樣可以更方便大家。

壓縮整合

CarbonIO能利用zlib或snappy對每一個數據包都進行壓縮/解壓縮,這一過程同樣是無需GIL的。

實戰檢驗

通過對一個繁忙的代理服務器(人數峰值大約1600人,一個平常工作日)的24小時數據的收集,我們發現CPU的總體使用率與單個用戶的CPU使用率都出現了大幅下降。

這都歸功于CarbonIO的總體架構,其作用就是降低事務的開銷。當服務器變得繁忙之后,這些優化的效果會被逐漸增多且必須處理的事務所抵消,但在最高負載時,CarbonIO還是讓我們的游戲增速了不少。

Python編寫EVE的具體思路

Python編寫EVE的具體思路

以上為24小時內單個用戶的CPU使用率

Python編寫EVE的具體思路

以上為同樣的24小時內總體CPU使用率

至于SOL(星系)節點,由于它們的主要職責是游戲機制而非網絡管理,因此它們從該優化中獲得的優勢并不那么明顯,但我們還是看到它們的CPU使用率下降了8%-10%。

需要指出的是,在上述的檢驗中我們沒有運用BlueNet,沒有用CarbonIO的數據導航,也沒有用脫離GIL的數據壓縮/解壓縮。

總的來說,比起以前,EVE能更好地利用現代服務器硬件帶來的優勢,能讓它在同樣的時間內完成更多的工作,這樣就間接提升了一個系統所能進行的操作上限。

通過將我們的代碼盡量與GIL脫離,我們反而為那些真正需要用它的代碼騰出了空間。另外,由于不再有那么多代碼需要競相獲取GIL,系統的總體運行效率也會提升。有了BlueNet再加上很好的代碼優化,提速空間已被打開。雖然最后的結果仍有待實踐檢驗,但至少,我們已經消除了一大瓶頸。

看完了這篇文章,相信你對Python編寫EVE的具體思路有了一定的了解,想了解更多相關知識,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

开阳县| 平江县| 泊头市| 教育| 当阳市| 共和县| 文登市| 明星| 西贡区| 岫岩| 江川县| 清镇市| 内江市| 柘城县| 阜康市| 黎平县| 灵璧县| 甘肃省| 威信县| 永顺县| 灯塔市| 信宜市| 安多县| 吴堡县| 宁河县| 张家口市| 洛隆县| 富宁县| 卓资县| 万安县| 柞水县| 礼泉县| 广平县| 襄汾县| 澄城县| 高雄县| 车险| 惠东县| 政和县| 东丽区| 莱西市|