揭開AI編程語言Mojo比Pyhon快6.8萬倍的5個(gè)秘密砂缩!

20240403133200

最近(2024年3月29日)庵芭,號稱比Python快6.8萬倍的Mojo編程語言開源啦雀监!6.8萬倍?你敢相信這個(gè)數(shù)字是真的嗎好乐?不過瓦宜,就連Mojo官網(wǎng)都把這個(gè)結(jié)果貼了出來(見下圖)临庇,這就很難讓你不對這個(gè)數(shù)字引起好奇昵慌。很顯然淮蜈,Mojo官方的結(jié)果難免有“自賣自夸”的嫌疑礁芦,但至少說明在某些特殊的場景下確實(shí)得到了這個(gè)數(shù)字,官網(wǎng)不會造假肖方。那么未状,究竟是什么原因讓Mojo能比Python快這么多呢?下面我們就揭開這一神秘的面紗艰垂,也借此機(jī)會讓我們進(jìn)一步了解Mojo這門比較火的編程語言猜憎。

20240403200358

Mojo簡介

Mojo編程語言是由Modular公司開發(fā)的搔课,旨在為人工智能領(lǐng)域提供統(tǒng)一的編程框架爬泥。它是基于Python語法的超集,結(jié)合了Python的易用性和C語言的性能踩官,支持多核境输、向量單元加速器單元等硬件功能嗅剖。Mojo能夠?qū)Υ罅康图堿I硬件進(jìn)行編程,模型擴(kuò)展性更強(qiáng)区匣,為開發(fā)者提供卓越的性能體驗(yàn)。Mojo的創(chuàng)始人是Chris Lattner莲绰,他是Swift語言的創(chuàng)始人姑丑,也參與了LLVM和Clang的開發(fā)。他與Google的機(jī)器學(xué)習(xí)產(chǎn)品經(jīng)理Tim Davis共同創(chuàng)立了Modular公司震肮,并在2022年推出了Mojo語言戳晌。

特殊的例子

可以猜想痴柔,這個(gè)6.8萬倍的結(jié)果是在一個(gè)特殊的例子上完成,具體來說豪嚎,它計(jì)算和繪制了Mandelbrot集谈火,就是下面的分圖案糯耍。這是一個(gè)非常簡單但是又非常耗費(fèi)計(jì)算資源的例子,測試者也給出了選擇這個(gè)作為例子的理由:

  • 簡單表達(dá):只有很少的代碼
  • 純計(jì)算:曼德勃羅集沒有內(nèi)存開銷
  • 容易并行
  • 可向量化

所以6.8萬倍的第1個(gè)秘密就是這個(gè)計(jì)算場景非常適合發(fā)揮Mojo的所有優(yōu)勢啦租,這是經(jīng)典的以己之長比別人之短荒揣。

20240403201325
# 代碼示例:下面函數(shù)中z是復(fù)數(shù)
MAX_ITERS = 1000
def mandelbrot_kernel(c): 
  z = c
  nv = 0
  for i in range(MAX_ITERS):
    if abs(z) > 2:
      break
    z = z*z + c
    nv += 1
  return nv

編譯語言vs解釋語言

眾所周知系任,Python是解釋型語言俩滥,性能上天然會有一些劣勢贺奠。Mojo是雖然語法上兼容Python(很多寫法上是一樣的),但卻是一個(gè)編譯語言挂据。除此之外崎逃,Mojo除了像Python一樣支持動態(tài)類型(在運(yùn)行的時(shí)候才知道變量的類型),還支持另一種靜態(tài)類型的寫法(見下面代碼示例)勒葱,當(dāng)使用靜態(tài)類型的時(shí)候編譯器可以提前對代碼做出很多針對性的優(yōu)化巴柿,提升性能篮洁。6.8萬倍的第2個(gè)秘密就是這Mojo是一門支持靜態(tài)類型的編譯語言

fn mandelbrot_2(c: ComplexFloat64) -> Int:
    var z = c
    var nv = 0
    for i in range(1, MAX_ITERS):
        if z.squared_norm() > 4:
            break
        z = z.squared_add(c)
        nv += 1
    return nv

向量化

前面兩個(gè)秘密其實(shí)還談不上多神秘瓦阐,很容易理解和想到篷牌。我認(rèn)為接下來談到的這個(gè)才算是Mojo真正厲害的地方枷颊。

正如宣傳所說,Mojo是面向人工智能的語言信卡,人工智能計(jì)算的特點(diǎn)是什么题造?大量的向量計(jì)算界赔。于是Mojo對向量計(jì)算進(jìn)行了針對性的優(yōu)化,并且這種優(yōu)化深入到了底層硬件咐低。為此袜腥,Mojo內(nèi)置了SIMD類型。

單指令多數(shù)據(jù)(SIMD)是一種并行處理技術(shù)鲤屡,內(nèi)置于許多現(xiàn)代CPU执俩、GPU和定制加速器中。SIMD允許您一次對多個(gè)數(shù)據(jù)執(zhí)行單個(gè)操作尝丐。例如衡奥,如果您想對數(shù)組中的每個(gè)元素求平方根矮固,可以使用SIMD來并行化工作。

Mojo中的SIMD類型就是專門負(fù)責(zé)針對不同的CPU/GPU進(jìn)行這種優(yōu)化的盹兢,具體是實(shí)現(xiàn)細(xì)節(jié)在這里就不展開了守伸。在原作者測試的機(jī)器上尼摹,CPU具有512bit長的向量寄存器,這意味著CPU可以一次操作512/64=8個(gè)雙精度浮點(diǎn)數(shù)玄呛,理論上可以實(shí)現(xiàn)8x的加速和二,實(shí)測結(jié)果是實(shí)現(xiàn)了6x以上的加速儿咱。此外场晶,原作者在SIMD的基礎(chǔ)上還進(jìn)行了進(jìn)一步針對CPU的指令的優(yōu)化:現(xiàn)代 x86 系統(tǒng)具有多個(gè)融合乘加(FMA)單元诗轻,使其能夠在每個(gè)時(shí)鐘周期執(zhí)行多個(gè) FMA。這一優(yōu)化也將速度再原有基礎(chǔ)上提升了一倍多吏颖,不過這一技巧很難適用于所有的計(jì)算場景,不多討論疚俱。

鑒于Mojo內(nèi)置了SIMD數(shù)據(jù)類型呆奕,所以實(shí)現(xiàn)上面的優(yōu)化并不算復(fù)雜衬吆,這一向量化加速的技術(shù)還真是非常適合人工智能計(jì)算的場景呢逊抡。6.8萬倍的第3個(gè)秘密就是SIMD向量化加速

多線程加速

Python實(shí)是單線程的拇勃,如果要利用多核CPU的特性還需要一些特殊的處理孝凌,很不方便胎许。Mojo是原生支持多線程的,可以很方便利用多核CPU的特性钩述。用多核CPU對比Python的單核CPU牙勘,這不是作弊嗎所禀?確實(shí)色徘,不過在這里我們先不談公平問題,先看看在Mojo中是如何實(shí)現(xiàn)多線程加速的横腿。

fn compute_row(chunk_idx:Int):
  let y = chunk_size * chunk_idx
  let cy = min_y + y * scale_y

  @parameter
  fn compute_vector[simd_width:Int](w:Int):
    let cx = min_x + iota[DType.float64, simd_width]() * scale_x
    output.simd_store[simd_width](Index(h,w), 
                                  mandelbrot_kernel(
                                               ComplexSIMD[DType.float64, 
                                               simd_width](cx,cy))
  vectorize[num_ports * simd_width, compute_vector](width)

  # !!! 重點(diǎn)代碼在這里
  with Runtime(num_cores()) as rt:
    parallelize[compute_row](rt, height)

實(shí)事求是的說耿焊,在Mojo中實(shí)現(xiàn)并行確實(shí)方便的多啊器腋!無論如何還是要為這一特性點(diǎn)個(gè)贊蒂培。所以6.8萬倍的第4個(gè)秘密就是多線程并行加速榜苫。

原作者測試的機(jī)器具有88個(gè)CPU垂睬,通過這一“作弊行為”,直接將性能在原有的基礎(chǔ)上提升了 30 倍钳枕,效果那是相當(dāng)明顯??赏壹。但是你可能好奇蝌借,為什么沒有提升到88倍呢?

負(fù)載均衡和數(shù)據(jù)傾斜

我相信“負(fù)責(zé)均衡”和“數(shù)據(jù)傾斜”這兩個(gè)概念至少有一個(gè)你是比較熟悉的自晰,通俗點(diǎn)講它們都反應(yīng)了一個(gè)問題:分工不均酬荞,活都讓少數(shù)人干了瞧哟。這就是上面的例子中為什么88核CPU只實(shí)現(xiàn)了30倍加速的原因:計(jì)算在88個(gè)CPU中并不是均勻分布的勤揩。那么如何進(jìn)一步優(yōu)化呢?

方法其實(shí)也并不復(fù)雜凿傅,我們可以把任務(wù)進(jìn)一步拆分成更小的單元数苫,拆分的越細(xì)聪舒,平均分配給每個(gè)cpu之后越不容易產(chǎn)生“分工不均”的現(xiàn)象(如果你寫過Spark,應(yīng)該聽過這個(gè)最佳實(shí)踐:任務(wù)/Task的數(shù)量最好是Executor/Core數(shù)量的2-3倍虐急,而不是等于)箱残。值得慶幸的是,Mojo 包含一個(gè)高性能并發(fā)運(yùn)行時(shí)止吁,因此我們不必自己創(chuàng)建線程池或進(jìn)行循環(huán)選擇和執(zhí)行被辑。Mojo 的運(yùn)行時(shí)包含高級功能,可以充分利用像這樣的多核系統(tǒng)敬惦。

# 只需要對原來代碼做很少改動
with Runtime(num_cores()) as rt:
    let partition_factor = 16 # Is autotuned.
    parallelize[compute_row](rt, height, partition_factor * num_cores())

6.8萬倍的第5個(gè)秘密就是負(fù)載均衡盼理。

總結(jié)

以上每一個(gè)優(yōu)化都會使得性能提升幾倍到數(shù)十倍不等,這些數(shù)字相乘之后確實(shí)就得到了6.8萬這一聳人聽聞的數(shù)字俄删。一路學(xué)習(xí)了解下來,我覺得Mojo確實(shí)是一門相當(dāng)不錯(cuò)的編程語言畴椰,同時(shí)Mojo團(tuán)隊(duì)也是很懂營銷半铩!

關(guān)注【黑客悟理】斜脂,不錯(cuò)過任何奇奇怪怪的知識

參考資料

  1. https://www.modular.com/blog/how-mojo-gets-a-35-000x-speedup-over-python-part-1
  2. https://www.modular.com/blog/how-mojo-gets-a-35-000x-speedup-over-python-part-2
  3. https://www.modular.com/blog/mojo-a-journey-to-68-000x-speedup-over-python-part-3
  4. https://mojocn.org/

如果你喜歡我的文章抓艳,歡迎到我的個(gè)人網(wǎng)站關(guān)注我,非常感謝帚戳!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末玷或,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子片任,更是在濱河造成了極大的恐慌庐椒,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蚂踊,死亡現(xiàn)場離奇詭異约谈,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)犁钟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進(jìn)店門棱诱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人涝动,你說我怎么就攤上這事迈勋。” “怎么了醋粟?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵靡菇,是天一觀的道長重归。 經(jīng)常有香客問我,道長厦凤,這世上最難降的妖魔是什么鼻吮? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮较鼓,結(jié)果婚禮上椎木,老公的妹妹穿的比我還像新娘。我一直安慰自己博烂,他們只是感情好香椎,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著禽篱,像睡著了一般畜伐。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上躺率,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天烤礁,我揣著相機(jī)與錄音,去河邊找鬼肥照。 笑死脚仔,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的舆绎。 我是一名探鬼主播鲤脏,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼吕朵!你這毒婦竟也來了猎醇?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤努溃,失蹤者是張志新(化名)和其女友劉穎硫嘶,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體梧税,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡沦疾,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了第队。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片哮塞。...
    茶點(diǎn)故事閱讀 38,599評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖凳谦,靈堂內(nèi)的尸體忽然破棺而出忆畅,到底是詐尸還是另有隱情,我是刑警寧澤尸执,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布家凯,位于F島的核電站缓醋,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏绊诲。R本人自食惡果不足惜送粱,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望驯镊。 院中可真熱鬧葫督,春花似錦竭鞍、人聲如沸板惑。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽冯乘。三九已至,卻和暖如春晒夹,著一層夾襖步出監(jiān)牢的瞬間裆馒,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工丐怯, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留喷好,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓读跷,卻偏偏與公主長得像梗搅,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子效览,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評論 2 348

推薦閱讀更多精彩內(nèi)容