<kbd id="5sdj3"></kbd>
<th id="5sdj3"></th>

  • <dd id="5sdj3"><form id="5sdj3"></form></dd>
    <td id="5sdj3"><form id="5sdj3"><big id="5sdj3"></big></form></td><del id="5sdj3"></del>

  • <dd id="5sdj3"></dd>
    <dfn id="5sdj3"></dfn>
  • <th id="5sdj3"></th>
    <tfoot id="5sdj3"><menuitem id="5sdj3"></menuitem></tfoot>

  • <td id="5sdj3"><form id="5sdj3"><menu id="5sdj3"></menu></form></td>
  • <kbd id="5sdj3"><form id="5sdj3"></form></kbd>

    import一個“太極”庫,讓Python代碼提速100倍!

    共 3996字,需瀏覽 8分鐘

     ·

    2022-12-08 16:09




    文章來源:量子位

    眾所周知,Python的簡單和易讀性是靠犧牲性能為代價的——

    尤其是在計(jì)算密集的情況下,比如多重for循環(huán)。

    不過現(xiàn)在,大佬胡淵鳴說了:

    只需import 一個叫做“Taichi”的庫,就可以把代碼速度提升100倍!

    不信?

    來看三個例子。

    計(jì)算素?cái)?shù)的個數(shù),速度x120

    第一個例子非常非常簡單,求所有小于給定正整數(shù)N的素?cái)?shù)。

    標(biāo)準(zhǔn)答案如下:

    815714fc614b37f9321f697808521800.webp

    我們將上面的代碼保存,運(yùn)行。

    當(dāng)N為100萬時,需要2.235s得到結(jié)果:

    f0ddf89308fcdc1701a0ba9467ee55dc.webp

    現(xiàn)在,我們開始施魔法。

    不用更改任何函數(shù)體,import“taichi”庫,然后再加兩個裝飾器:

    86c37d4383b23a9800916854d51d7156.webp

    Bingo!同樣的結(jié)果只要0.363s,快了將近6倍。

    d6e57abdf4339d51dae5c3b31b130290.webp

    如果N=1000萬,則只要0.8s;要知道,不加它可是55s,一下子又快了70倍!

    不止如此,我們還可以在ti.init()中加個參數(shù)變?yōu)閠i.init(arch=ti.gpu) ,讓taich在GPU上進(jìn)行計(jì)算。

    那么此時,計(jì)算所有小于1000萬的素?cái)?shù)就只耗時0.45s了,與原來的Python代碼相比速度就提高了120倍!

    厲不厲害?

    什么?你覺得這個例子太簡單了,說服力不夠?我們再來看一個稍微復(fù)雜一點(diǎn)的。

    動態(tài)規(guī)劃,速度x500

    動態(tài)規(guī)劃不用多說,作為一種優(yōu)化算法,通過動態(tài)存儲中間計(jì)算結(jié)果來減少計(jì)算時間。

    我們以經(jīng)典教材《算法導(dǎo)論》中的經(jīng)典動態(tài)規(guī)劃案例“最長公共子序列問題(LCS)”為例。

    比如對于序列a = [0, 1, 0, 2, 4, 3, 1, 2, 1]和序列b = [4, 0, 1, 4, 5, 3, 1, 2],它們的LCS就是:

    LCS(a, b) = [0, 1, 4, 3, 1, 2]。

    用動態(tài)規(guī)劃的思路計(jì)算LCS,就是先求解序列a的前i個元素和序列b的前j個元素的最長公共子序列的長度,然后逐步增加i或j的值,重復(fù)過程,得到結(jié)果。

    我們用f[i, j]來指代這個子序列的長度,即LCS((prefix(a, i), prefix(b, j)。其中prefix(a, i) 表示序列a的前i個元素,即a[0], a[1], …, a[i - 1],得到如下遞歸關(guān)系:

    134bff9cce6b129e21cf675a47858b56.webp

    現(xiàn)在,我們用Taichi來加速:

    a38126d4b711ea3ac2ef71c260925780.webp

    結(jié)果如下:

    e91507324ad1a11376cce59844ae0d3e.webp

    胡淵鳴電腦上的程序最快做到了0.9秒內(nèi)完成,而換成用NumPy來實(shí)現(xiàn),則需要476秒,差異達(dá)到了超500倍!

    最后,我們再來一個不一樣的例子。

    反應(yīng) - 擴(kuò)散方程,效果驚人

    自然界中,總有一些動物身上長著一些看起來無序但實(shí)則并非完全隨機(jī)的花紋。

    4259686ea4d12c28fb49792fc646da33.webp

    圖靈機(jī)的發(fā)明者艾倫·圖靈是第一個提出模型來描述這種現(xiàn)象的人。

    在該模型中,兩種化學(xué)物質(zhì)(U和V)來模擬圖案的生成。這兩者之間的關(guān)系類似于獵物和捕食者,它們自行移動并有交互:

    1. 最初,U和V隨機(jī)分布在一個域上;

    2. 在每個時間步,它們逐漸擴(kuò)散到鄰近空間;

    3. 當(dāng)U和V相遇時,一部分U被V吞噬。因此,V的濃度增加;

    4. 為了避免U被V根除,我們在每個時間步添加一定百分比 (f) 的U并刪除一定百分比 (k) 的V。

    上面這個過程被概述為“反應(yīng)-擴(kuò)散方程”:

    8ec2513b97a1c48b61789bb889aa335e.webp

    其中有四個關(guān)鍵參數(shù):Du(U的擴(kuò)散速度),Dv(V的擴(kuò)散速度),f(feed的縮寫,控制U的加入)和k(kill的縮寫,控制V的去除)。

    如果Taichi中實(shí)現(xiàn)這個方程,首先創(chuàng)建網(wǎng)格來表示域,用vec2表示每個網(wǎng)格中U, V的濃度值。

    拉普拉斯算子數(shù)值的計(jì)算需要訪問相鄰網(wǎng)格。為了避免在同一循環(huán)中更新和讀取數(shù)據(jù),我們應(yīng)該創(chuàng)建兩個形狀相同的網(wǎng)格W×H×2。

    每次從一個網(wǎng)格訪問數(shù)據(jù)時,我們將更新的數(shù)據(jù)寫入另一個網(wǎng)格,然后切換下一個網(wǎng)格。那么數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)就是這樣:

    852ca54fd52d82d8b4d9986c32a6a2bf.webp

    一開始,我們將U在網(wǎng)格中的濃度設(shè)置為 1,并將V放置在50個隨機(jī)選擇的位置:

    64df60051861774a81b98b026f84fc67.webp

    那么實(shí)際計(jì)算就可以用不到10行代碼完成:

        @ti.kernel
    def?compute(phase:?int):
    ????for?i,?j?in?ti.ndrange(W,?H):
    ????????cen?=?uv[phase,?i,?j]
    ????????lapl?=?uv[phase,?i?+?1,?j]?+?uv[phase,?i,?j?+?1]?+?uv[phase,?i?-?1,?j]?+?uv[phase,?i,?j?-?1]?-?4.0?*?cen
    ????????du?=?Du?*?lapl[0]?-?cen[0]?*?cen[1]?*?cen[1]?+?feed?*?(1?-?cen[0])
    ????????dv?=?Dv?*?lapl[1]?+?cen[0]?*?cen[1]?*?cen[1]?-?(feed?+?kill)?*?cen[1]
    ????????val?=?cen?+?0.5?*?tm.vec2(du,?dv)
    ????????uv[1?-?phase,?i,?j]?=?val

    在這里,我們使用整數(shù)相位(0或1)來控制我們從哪個網(wǎng)格讀取數(shù)據(jù)。

    最后一步就是根據(jù)V的濃度對結(jié)果進(jìn)行染色,就可以得到這樣一個效果驚人的圖案?

    a477cb75bb8d145b6a458b742db800dc.webp

    ?有趣的是,胡淵鳴介紹,即使V的初始濃度是隨機(jī)設(shè)置的,但每次都可以得到相似的結(jié)果。

    而且和只能達(dá)到30fps左右的Numba實(shí)現(xiàn)比起來,Taichi實(shí)現(xiàn)由于可以選擇GPU作為后端,輕松超過了 300fps。

    pip install即可安裝

    看完上面三個例子,你這下相信了吧?

    其實(shí),Taichi就是一個嵌入在Python中的DSL(動態(tài)腳本語言),它通過自己的編譯器將被 @ti.kernel 裝飾的函數(shù)編譯到各種硬件上,包括CPU和GPU,然后進(jìn)行高性能計(jì)算。

    有了它,你無需再羨慕C++/CUDA的性能。

    正如其名,Taichi就出自太極圖形胡淵鳴的團(tuán)隊(duì),現(xiàn)在你只需要用pip install就能安裝這個庫,并與其他Python庫進(jìn)行交互,包括NumPy、Matplotlib和PyTorch等等。

    當(dāng)然,Taichi用起來和這些庫以及其他加速方法有什么差別,胡淵鳴也給出了詳細(xì)的優(yōu)缺點(diǎn)對比,感興趣的朋友可以戳下面的鏈接詳細(xì)查看:

    https://docs.taichi-lang.org/blog/accelerate-python-code-100x

    我們爬蟲第三期來了,加入我們,學(xué)更實(shí)用,更值錢的 Python 技術(shù)!

    
                
    
                  


    c71582d4f9a2567baa127d2f6a890567.webp


    從0到1系統(tǒng)掌握Python 技術(shù)(入門進(jìn)階)

    2個企業(yè)實(shí)戰(zhàn)項(xiàng)目,4大常用工具

    掌握24種反爬策略手段,成為真正爬蟲高手

    能抓取市面上90%的網(wǎng)站

    掌握主流爬蟲技術(shù),就業(yè)找工作 真正全方位幫助大家從0到1,從 Python 入門到進(jìn)階,轉(zhuǎn)行找爬蟲工作。

    瀏覽 57
    點(diǎn)贊
    評論
    收藏
    分享

    手機(jī)掃一掃分享

    分享
    舉報(bào)
    評論
    圖片
    表情
    推薦
    點(diǎn)贊
    評論
    收藏
    分享

    手機(jī)掃一掃分享

    分享
    舉報(bào)

    <kbd id="5sdj3"></kbd>
    <th id="5sdj3"></th>

  • <dd id="5sdj3"><form id="5sdj3"></form></dd>
    <td id="5sdj3"><form id="5sdj3"><big id="5sdj3"></big></form></td><del id="5sdj3"></del>

  • <dd id="5sdj3"></dd>
    <dfn id="5sdj3"></dfn>
  • <th id="5sdj3"></th>
    <tfoot id="5sdj3"><menuitem id="5sdj3"></menuitem></tfoot>

  • <td id="5sdj3"><form id="5sdj3"><menu id="5sdj3"></menu></form></td>
  • <kbd id="5sdj3"><form id="5sdj3"></form></kbd>
    久久丝袜| 大伊人中文字幕 | 国产黄色毛片网站 | 亚洲黄色视频网站 | A片黄色网 |