Pythoni jõudlus: natiivsed NumPy silmused, tagasihelistamised ja konversioonikulud
Kontrollitud ainult CPU-l põhinev numbriline test jälgib identseid väärtusi läbi CPythoni silmuste, NumPy aritmeetika, Pythoni tagasihelistamise ümbrise ja kompileeritud Numba silmuse.
Kontrollitud ainult CPU-l põhinev numbriline test jälgib identseid väärtusi läbi CPythoni silmuste, NumPy aritmeetika, Pythoni tagasihelistamise ümbrise ja kompileeritud Numba silmuse. Valmis sisend-NumPy-l oli suur edumaa, samas kui konversioon Pythoni loenditest ja tagasi Pythoni loenditesse vähendas selle eelise peaaegu viigini. Episood selgitab täitmise piiri ja seda, kuidas mõõta rakenduse vajalikku tulemust.
Loe kirjalikku väljaannet (inglise keeles) ↗
Mida see video hõlmab
- CPython kompileerib lähtekoodi baitkoodiks. Korduv interpretaatori/objekti töö ja tüübitud natiivne numbriline silmus on erinevad täitmiskorraldused.
- Numbriline NumPy aritmeetika saab anda tüübitud partiisid kompileeritud operatsioonidele; aritmeetiline silmus on endiselt olemas ja vaadetel võib olla mittejärjestikune paigutus.
- Mõõtke konversiooni ja nõutavat väljundi esitust. Selles käitus vähendas Pythoni loendite massiivideks ja tagasi teisendamine suure valmismassiivi eelise.
- Väikesed töökoormused võivad eelistada tavalist Pythoni, sest fikseeritud massiivi-kõne kulud on olulised. Kaheksa väärtusega mõistmine võitis selle mõõdetud võrdluse.
- np.vectorize on mugavusümbris, mis kutsub Pythoni järjestikuste elementide jaoks; ainult partiiliides ei loo natiivset numbrilist täitmist.
- Kompileeritud Pythoni-süntaksiga silmused võivad samuti olla kiired. Lisage külma kompileerimise/seadistamise kulud, kui need on kutsujale olulised.
- Natiivne täitmine, CPU SIMD, mitmelõimeline ja GPU taustaprogrammid on eraldi ideed. Saadaolevad CPU funktsioonid ei jälgi konkreetses käituses kasutatud juhiseid.
Tõlgitud transkriptsioon
Tõlgitud ingliskeelsest originaaljutustusest. Saadaolevat heli ja subtiitreid kontrollib YouTube.
Miks saab sama CPU varem valmis?
0:00 Arvate, et Python vajab kiiruse saamiseks uut keelt. Sama CPU käivitas meie partii kiiremini pärast silmuse liigutamist. Kuhu töö läks? Millal kiirus kaob? Milline otsetee toob Pythoni tagasi? See on The Daily Diff, sügavamalt vaadatuna. Hoidke sellel otseteel silm peal. CPython on standardne Pythoni implementatsioon.
0:17 See kompileerib teie lähtekoodi baitkoodiks, seejärel käivitab need instruktsioonid interpretaatoris. NumPy on numbriline teek, mille massiivid sisaldavad deklareeritud andmetüübiga väärtusi. Sellel on deklareeritud andmetüüp. Selle sisseehitatud aritmeetika saab anda kogu partii kompileeritud operatsioonidele. Võtke miljon ujukomaarvu, ruudutage igaüks, seejärel lisage algne väärtus. Iga versioon saab identsed väärtused ja annab sobivad vastused. Väärtused on piisavalt väikesed, et hoida ümardamisvahed võistlusest eemal.
0:40 Sellel masinal võttis mõistmine aega umbes kolmkümmend kolm millisekundit. NumPy võttis vähem kui ühe. Mõlemad töötasid CPU-l. See on kasulik tõend selle töökoormuse kohta ja kohutav järelehüüe programmeerimiskeelele. Alustage tavalise silmusega.
Millist tööd Pythoni silmus kordab?
0:53 Python võtab järgmise väärtuse, teostab aritmeetika ja lisab vastuse. Seejärel teeb seda uuesti. Korrutamine on odav. Järgmise korrutamise korraldamine ja selle ümber Pythoni objektide käsitlemine lisab iga kord tööd. See on testitud funktsiooni tegelik disasambleerimine. Kordus, korrutamine ja liitmine ilmuvad baitkoodi instruktsioonidena. Pythoni versioonid ja interpretaatorid teevad erinevaid valikuid.
1:14 Need ajad kuuluvad ekraanil olevale versioonile, mis on Python kolm koma kümme. Pythoni loend salvestab viiteid objektidele, nii et erinevad asjad saavad jagada loendit. Meie aritmeetiline töö kasutab pidevalt numbreid. See maksab üldise korralduse eest, nõudes samal ajal korduvat teenust. Kujutage ette, et tellite sama kohvi miljon korda ja täidate iga tassi jaoks värske vormi. iga tassi jaoks. Kohvimasin on korras.
1:36 Paberimajandus on arendanud oma karjääri.
Kuhu NumPy silmuse liigutab?
1:38 NumPy muudab lepingut. See massiiv sisaldab fikseeritud suurusega ujukomaarve ühe deklareeritud tüübiga. Meie massiiv on pidev, nii et selle väärtused asuvad mälus koos. Vaadetel võivad olla ka teised paigutused. Aritmeetiline operatsioon teab, millist tüüpi andmeid see saab. Kõne annab partii natiivsele operatsioonile. Silmus külastab endiselt väärtusi kompileeritud koodi sees. See saab taaskasutada teadmisi tüübist kogu selle töö ulatuses.
2:00 Python jääb isikuks, kes töö üle annab. Itamar Turner Trauring selgitab seda eristust raamatus Python Speed. Partii liidesed, natiivsed implementatsioonid ja protsessori vektorinstruktsioonid on eraldi asjad. Funktsiooni nimi annab väga vähe tõendeid.
Kas kiire tähendab GPU-d või mitut CPU tuuma?
2:13 See tulemus kasutas NumPy-d CPU-l. GPU taustaprogramm, näiteks CuPy, valib massiividele ja operatsioonidele teise koha. GPU ostmine jätab selle tavalise Pythoni silmuse tööle sinna, kus see juba töötas. CPU vektorinstruktsioonid saavad töödelda mitut väärtust koos. NumPy-l on mehhanismid toetatud tuumade valimiseks. Meie käitusaeg annab aru saadaolevatest funktsioonidest, kuid ei jälgi selle avaldise juhiseid. Kogu mõõdetud kasu andmine vektorinstruktsioonidele müüks tõendeid üle.
2:40 GPU ostukorv võib jääda suletuks. On midagi sügavalt rahuldavat jõudlusparanduses, mis ka tühistab ostu. Kahjuks jätkub võrdlus.
Millal muljetavaldav kiirendus kaob?
2:49 Kaheksa väärtuse puhul võitis mõistmine. Massiivimehhanismi kutsumine maksis rohkem kui väike töö. Suuremad valmis massiivid tõusid ette. Kasutasime korduvaid katseid ja soojendatud protsessi. Uuemad Pythoni versioonid võivad ülemineku muuta. Seejärel muutke, mida rakendus vajab. Alustage Pythoni loendiga ja lõpetage värske Pythoni loendiga. NumPy peab sisendi teisendama massiiviks ja vastuse tagasi Pythoni
3:11 objektideks muutma. Need sammud kuuluvad arvele, kui teie rakendus neid vajab. Miljoni väärtuse puhul võttis see täielik tee umbes kakskümmend kaheksa millisekundit. Mõistmine võttis ka umbes kakskümmend kaheksa. Meie dramaatiline edumaa muutus peaaegu viigiks. Kiire osa oli reaalne. Eelis sõltus sellest, et andmed said jääda oma numbrilisse vormi.
Millised piirid kuuluvad võrdlusesse?
3:28 Järgige andmeid. Kui järgmine operatsioon aktsepteerib massiivi, hoidke massiivi. Kui teisendate korduvalt loendite ja massiivide vahel, mõõtke neid üleminekuid. Kallite ülekannete peatamine annab vale küsimuse kohta täpsed numbrid. Selle massiivi korrutamine loob ajutise tulemuse. Algväärtuste liitmine loob väljundi. Natiivne täitmine vajab endiselt mälu ja liigutab andmeid.
3:47 Mõned operatsioonid aktsepteerivad väljundpuhvrit, vähendades eraldusi, kui teie kood saab seda ohutult taaskasutada. Üks ilus rida saab tellida mitu suurt puhvrit. Sellele probleemile viitab ka Python Speed. Eraldaja on teie esteetika suhtes märkimisväärselt ükskõikne.
Kas kompileeritud Pythoni silmus võib ka kiire olla?
4:00 Saate säilitada ka silmuse süntaksi ja muuta selle täitmist. Numba saab kompileerida toetatud numbrilisi Pythoni funktsioone natiivkoodiks. Siin on meie testi silmus koos selle kompilaatori dekoraatoriga. See ütleb endiselt "for". Kallis interpretaatori tee on muutunud. Pärast kompileerimist võttis see silmus valmis massiividega vähem kui pool millisekundit. Kompileerimine ise võttis selles käitus umbes sekundi. See seadistuskulu jäeti korduvast ajastamisest välja,
4:22 nii et pisike ühekordne töö väärib teistsugust võrdlust. Numba enda juhend näitab hea meelega selgesõnalisi silmuseid. Keele migreerimise alustamine enne kuuma tee leidmist on keeruline viis profiileri avamise vältimiseks. Kõigepealt leidke, mis aega kulutab. Võrgule ootamine, objektide parsimine ja hulgiaritmeetika vajavad erinevaid parandusi. Natiivsed massiivioperatsioonid aitavad, kui arvutamine ja andmed sobivad.
4:43 Mõõtke tulemus, mida teie kutsuja tegelikult vajab. Nüüd selle otsetee kohta. Teil on Pythoni funktsioon ja soovite, et see aktsepteeriks massiivi. Ümbris nimega vectorize kõlab nagu puuduv jõudlusnupp. Selle dokumentatsioonis ootab oluline lause.
Mida np.vectorize tegelikult täidab?
4:56 NumPy ütleb, et selle vectorize ümbris on pakutud peamiselt mugavuse pärast. Selle implementatsioon on sisuliselt for-tsükkel. Ümbris aktsepteerib partiisid, kuid jätkab teie Pythoni funktsiooni kutsumist järjestikuste elementide jaoks. Liides lühenes. Täitmise piir jäi hõivatuks. Vaadake samu väärtusi Pythoni tagasihelistamise kaudu tagasi tulemas. Valmis massiividega võttis see versioon umbes kaheksakümmend seitse millisekundit. See oli aeglasem kui meie mõistmine.
5:18 Kasulik levitusümbris võib säilitada täpselt selle elemendipõhise töö, mida proovisite eemaldada. Kontrollige partiiliidese taga olevat implementatsiooni, hoidke ühilduvad andmed nende kasulikus vormis ja kaasake teisendamine võrdlusesse. Natiivsed, tagasihelistamise ja kompileeritud silmused võivad helistaja seisukohast tunduda sarnased. Nimi vectorize andis lubaduse, mida teie stopper kunagi ei allkirjastanud. Hoidke seda, kui mugavus on see, mida vajate. Jõudluse osas kontrollige töötavat silmust.
Mida peaksite oma koodis muutma?
5:41 Minu otsus on SHIP IT mõõdetud numbrilise kuuma tee partiidena töötlemiseks. Hoidke tavalisi silmuseid, kui need juba hästi töötavad. Kontrollige, kus töö toimub ja mida järgmine kutsuja vajab. Telli, vajuta kella ja ütle mulle kommentaarides, kas oleksite sellele erinevalt templi pannud. Ja see on tänane vahe. Mina olen Niko Axrisist. Ühenda vastutustundlikult.
Allikad
- Universal functions (ufunc) basics — NumPy 2.2NumPy
- The N-dimensional array — NumPy 2.2NumPy
- numpy.vectorize — convenience and performance notesNumPy
- CPU/SIMD optimizations — NumPy 2.2NumPy
- dis — Disassembler for Python bytecodePython Software Foundation
- CPython 3.10.12 list representationCPython contributors
- The limits of Python vectorization as a performance techniqueItamar Turner-Trauring / Python⇒Speed
- Performance TipsNumba
- Basics of CuPyCuPy



