EVE 居然是用 python 寫的!!太不可思議了
大多數熟悉EVE的人都知道,它是用Python語言編寫的,如果要說得更具體點,那就是Stackless Python。Stackless是在Python基礎上編寫的一套微執行緒框架,它能在不產生大量Python自身額外開銷的情況下同時容納數百萬條的執行緒。但話還是要說回來,它畢竟還是Python,因此擺脫不了“直譯器全域性鎖”(Global Interpreter Lock,下文將其簡稱為GIL)。
GIL是一個序列鎖,用來保證在任何時候都只能有一個執行緒利用Python直譯器(包括其所有資料)來執行自己。因此,儘管Stackless Python感覺上好像具備多執行緒處理能力,但實際上它還是單執行緒的,只不過運用了任務分離、頻道、定時器及共享記憶體等一系列招數而已。其實過去有些協作式的多工作業系統也是這樣乾的,其好處是保證了所有執行緒都能被執行,不會出現被作業系統提前結束這一情況(除非被作業系統懷疑非法宕機)。GIL的存在使得程式設計師在編寫遊戲邏輯時能自信推斷出程式的全域性狀態,省去了一大堆採用非同步回撥函式的麻煩。
但這樣有一大缺點:由於EVE中有部分框架的程式碼是用Python編寫的,因此它們都免不了GIL造成的負面影響。比如,一段用來讀取Python資料的C++語言程式碼必須在獲得GIL後才能讀取一個字串。
使用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。
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了。
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還是讓我們的遊戲增速了不少。
以上為24小時內單個使用者的CPU使用率
以上為同樣的24小時內總體CPU使用率
至於SOL(星系)節點,由於它們的主要職責是遊戲機制而非網路管理,因此它們從該優化中獲得的優勢並不那麼明顯,但我們還是看到它們的CPU使用率下降了8%-10%。
需要指出的是,在上述的檢驗中我們沒有運用BlueNet,沒有用CarbonIO的資料導航,也沒有用脫離GIL的資料壓縮/解壓縮。
總結
總的來說,比起以前,EVE能更好地利用現代伺服器硬體帶來的優勢,能讓它在同樣的時間內完成更多的工作,這樣就間接提升了一個系統所能進行的操作上限。通過將我們的程式碼儘量與GIL脫離,我們反而為那些真正需要用它的程式碼騰出了空間。另外,由於不再有那麼多程式碼需要競相獲取GIL,系統的總體執行效率也會提升。有了BlueNet再加上很好的程式碼優化,提速空間已被開啟。雖然最後的結果仍有待實踐檢驗,但至少,我們已經消除了一大瓶頸。
相關推薦
EVE 居然是用 python 寫的!!太不可思議了
大多數熟悉EVE的人都知道,它是用Python語言編寫的,如果要說得更具體點,那就是Stackless Python。Stackless是在Python基礎上編寫的一套微執行緒框架,它能在不產生大量Python自身額外開銷的情況下同時容納數百萬條的執行緒。但話還是要說
10分鐘學會用python寫遊戲!Python其實很簡單!
安裝pygame 本人電腦是windows 10、python3.6,pygame下載地址: https://pypi.python.org/pypi/Pygame/1.9.3 請自行下載對應python版本的 pygame 執行以下命令 &nb
新型勒索病毒居然是Python寫的?如果遇到了該怎麼辦呢?
這個新型的勒索病毒叫Dablio,理論上可以感染下列檔案型別,也就是你電腦中以下列名字作為字尾名的檔案,全部打不開 看了上面的檔案型別,我也服了。這做毒的比我還想的周到。。。合著有點用的檔案全想感染。。。 進
給女朋友用Python寫了一個自動抽獎程序!Python在手,獎品我有!
com () 單身 代碼 女孩子 nbsp 不能 是不是 apt 我相信大部分的女孩子都是喜歡買買買的,我還沒有見過不喜歡買東西的女孩子,當然很多東西也是有抽獎這項優惠的,很多小程序都有抽獎這個功能的,好了廢話不多說了,為了給女朋友寫這款抽獎程序,可謂是嘔心瀝血!不過看到她
女朋友是機票販子?用Python寫個刷飛機票的指令碼!生活費多了兩百
進群:548377875 即可獲取數十套PDF從零基礎到專案實戰的哦! 看到上面的介面你是否也有下面的感受: 簡單描述一下eterm的操作流程,方便理解指令碼的
用Python寫了個色情文章檢測器!投放各大自媒體!就年薪百萬了?
但是,有些作者發表的文章充斥著色情與暴力,一旦被青少年看到,會產生難以想象的後果。我們需要對網路上的文章進行檢測,以標記出其是否為色情文章,如果是,那麼我們就要將其過濾不予顯示。而人工檢測在資訊爆炸的今天幾乎不可能實現。所以,我們提出了基於神經網路的色情文章檢測。 具體的
我用Python寫了一個共享單車的應用程式!下一個摩拜單車會是我嗎
學習如何使用 Redis 和 Python 構建一個位置感知的應用程式。 我經常出差。但不是一個汽車狂熱分子,所以當我有空閒時,我更喜歡在城市中散步或者騎單車。我參觀過的許多城市都有共享單車系統,你可以租個單車用幾個小時。大多數系統都有一個應用程式來幫助使用者定位和租用他們的單車,但對於像我這樣
驚!女朋友用Python寫出幾行程式碼就監控了我的電腦,吃雞被發現了
今天帶給大家一個非常有意思的 python 程式,基於 itchat 實現微信控制電腦。你可以通過在微信傳送命令,來拍攝當前電腦的使用者,然後圖片會發送到你的微信上。甚至你可以傳送命令來遠端關閉電腦。 學習Python中有不明白推薦加入交流裙  
究極大福利!用Python寫一個抖音漂亮小姐姐發掘器!原始碼送給你!
最近沉迷於抖音無法自拔,常常連續花好幾個小時在抖音漂亮小姐姐身上。手動尋找費時費力,為了高效、直接地找到漂亮小姐姐,我用 Python + ADB 做了一個 Python 抖音機器人 Douyin-Bot。自動翻頁+顏值識別,瞬間覺得關注列表不夠用了!原理開啟《抖音短視訊》APP,進入主介面獲取手機截圖,並對
用python寫王者榮耀指令碼!
00. 前言 今天這篇文章我想很多人都有想過,比如說指令碼自動走位,對於王者榮耀和英雄聯盟都是怪物級別的存在。但是還是覺得有些不夠熟練,自己試過幾次才成功。 01. 目錄檔案分類 前言 有時候,想要對一個目錄裡的檔案進行搜尋或者分類操作往往是一件痛苦的事情,下面這個程式的目的是將目錄
比12306快!用Python寫一個火車票檢視器~
當你準備出去玩,想查詢一下火車票資訊的時候,還在用12306官網嗎?下面我們用 Python 寫一個命令列版的火車票檢視器, 只要在命令列敲一行命令就能獲得你想要的火車票資訊! 一、實驗簡介 1.1 知識點 Python3 基礎知識的綜合運用 docopt、requests 及 prett
人人都能用Python寫出LSTM-RNN的程式碼![你的神經網路學習最佳起步]
0. 前言 本文翻譯自部落格: iamtrask.github.io ,這次翻譯已經獲得trask本人的同意與支援,在此特別感謝trask。本文屬於作者一邊學習一邊翻譯的作品,所以在用詞、理論方面難免會出現很多錯誤,假如您發現錯誤或者不合適的地方,可以給我留言,謝謝! -
人人都能用Python寫出LSTM-RNN的程式碼!
0. 前言 本文翻譯自部落格: iamtrask.github.io ,這次翻譯已經獲得trask本人的同意與支援,在此特別感謝trask。本文屬於作者一邊學習一邊翻譯的作品,所以在用詞、理論方面難免會出現很多錯誤,假如您發現錯誤或者不合適的地方,可以給我留言,謝謝! 1. 概要 我的最佳學習法就是通過玩
用Python寫出LSTM-RNN的程式碼!
0. 前言 本文翻譯自部落格: iamtrask.github.io ,這次翻譯已經獲得trask本人的同意與支援,在此特別感謝trask。本文屬於作者一邊學習一邊翻譯的作品,所以在用詞、理論方面難免會出現很多錯誤,假如您發現錯誤或者不合適的地方,可以給我留言,謝謝!
中國新說唱熱門歌曲有哪些?今天我們就用Python來分析!
之前風靡朋友圈的“skr”流行語把中國新說唱這一節目帶上了熱議高峰,本文就來分析下,如何用Python爬取大受歡迎的說唱歌曲。 首先登入https://music.163.com/ 網易雲音樂搜尋新說唱,開啟Chrome的開發工具工具選擇Network並重新載入頁面,找到與評論資料相關的請求即n
你還在看付費VIP視訊?小編教你用Python任意下!
我相信如果看電影的都知道,不管是愛奇藝還是騰訊視訊還是優酷很多的電影電視都是需要VIP的,但是為了看這麼一個電視或者電影開個vip又不是很划算,那麼就有人問小編了可不可以找到視訊的解析口看電影啊? 答案是:可以的。 好了,廢話不多說。現在開始我們的實戰之旅吧! 實
我居然用爬蟲把boss資料爬取了!我會不會死的很慘?
一、概述 學習python有一段時間了,最近了解了下Python的入門爬蟲框架Scrapy,參考了文章 Python爬蟲框架Scrapy入門 。本篇文章屬於初學經驗記錄,比較簡單,適合剛學習爬蟲的小夥伴。 這次我選擇爬取的是boss直聘來資料,畢竟這個網站的資料還是很有參考價值的,下面我們講
手把手教你用Python去除馬賽克!
有人說,馬賽克是阻礙人類進步的絆腳石,雖然最近幾年也頻繁傳出有在研發去除馬賽克的軟體,但是一直沒有成品問世。 於是人類和馬賽克的鬥爭就從未消停過。各種有亮點的圖片部位,經常被無情地打上馬賽克。在此之前,想完美清除馬賽克幾乎是不可能的,人類的進步一直停留在怎麼打馬賽克和去馬賽克之間。 最近一位
七夕快到了,教你用python去表白!
# -*- coding: utf-8 -*- import sys from PyQt5 import QtWidgets from PyQt5.QtGui import QFont,QIcon#QtWidgets不包含QFont必須呼叫QtGui from PyQt5 i
用Python寫一個批量生成賬號的函數(用戶控制數據長度、數據條數)
shuf open 小寫 長度 數據 ase 函數 用戶控制 app # 1、寫一個函數,批量生成一些註冊使用的賬號:[email protected]/* */,長度由用戶輸入,產生多少條也由用戶輸入,用戶名不能重復,用戶名必須由大寫字母、小寫字母、數字組成