Python performansı: yerli NumPy döngüləri, geri zənglər və çevirmə xərcləri
Nəzarətli, yalnız CPU-da işləyən rəqəmsal test CPython döngələri, NumPy arifmetikası, Python geri zəng "wrapper"-i və tərtib edilmiş Numba döngəsi vasitəsilə eyni dəyərləri izləyir.
Nəzarətli, yalnız CPU-da işləyən rəqəmsal test CPython döngələri, NumPy arifmetikası, Python geri zəng "wrapper"-i və tərtib edilmiş Numba döngəsi vasitəsilə eyni dəyərləri izləyir. Hazır girişli NumPy böyük üstünlüyə malik idi, Python siyahılarından çevirmə və geri qaytarma bu üstünlüyü demək olar ki, bərabər səviyyəyə endirdi. Epizod icra sərhədini və bir tətbiqin ehtiyac duyduğu nəticəni necə ölçməyi izah edir.
Yazılı nəşri oxuyun (İngiliscə) ↗
Bu videoda nələr əhatə olunur
- CPython mənbəyi baytkoda tərtib edir. Təkrar olunan tərcüməçi/obyekt işi və tipli yerli rəqəmsal döngə müxtəlif icra tənzimləmələridir.
- Rəqəmsal NumPy arifmetikası tipli topluları tərtib edilmiş əməliyyatlara ötürə bilər; arifmetik döngə hələ də mövcuddur və görünüşlər qeyri-ardıcıl düzülüşlərə malik ola bilər.
- Çevirməni və tələb olunan çıxış təqdimatını ölçün. Bu işdə Python siyahılarını massivlərə çevirmək və geri qaytarmaq böyük hazır massiv üstünlüyünü ləğv etdi.
- Kiçik iş yükləri adi Python-a üstünlük verə bilər, çünki sabit massiv-çağırma xərcləri vacibdir. Səkkiz dəyərli "comprehension" bu ölçülmüş müqayisədə qalib gəldi.
- np.vectorize ardıcıl elementlər üçün Python-u çağıran bir rahatlıq "wrapper"-idir; təkcə toplu interfeysi yerli rəqəmsal icra etmir.
- Tərtib edilmiş Python-sintaksis döngələri də sürətli ola bilər. Zəng edən üçün vacib olduqda soyuq tərtib/quraşdırma xərclərini daxil edin.
- Yerli icra, CPU SIMD, çoxlu iş parçacığı və GPU backendləri ayrı fikirlərdir. Mövcud CPU xüsusiyyətləri müəyyən bir işdə istifadə olunan təlimatları izləmir.
Tərcümə olunmuş transkript
Orijinal ingilis dilindəki nəqldən tərcümə edilmişdir. Mövcud audio və subtitrlər YouTube tərəfindən idarə olunur.
Niyə eyni CPU daha tez bitirə bilər?
0:00 Sizcə Python-un sürətli olmaq üçün yeni bir dilə ehtiyacı var. Eyni CPU, döngə köçürüldükdən sonra toplumumuzu daha sürətli işlətdi. İş hara getdi? Sürətlənmə nə vaxt yox olur? Hansı qısayol Python-u geri gətirir? Bu, pərdə arxasında The Daily Diff-dir. Bu qısayolu gözləyin. CPython standart Python tətbiqidir.
0:17 O, mənbənizi baytkoda tərtib edir, sonra həmin təlimatları bir tərcüməçidə işlədir. NumPy rəqəmsal kitabxanadır, onun massivləri elan edilmiş məlumat növü ilə dəyərləri saxlayır. Onun daxili arifmetikası bütöv bir partiyanı tərtib edilmiş əməliyyatlara ötürə bilər. Bir milyon float dəyər götürün, hər birini kvadrat edin, sonra orijinal dəyəri əlavə edin. Hər versiya eyni dəyərlər alır və uyğun cavablar verir. Dəyərlər yuvarlaqlaşdırma fərqlərini yarışdan kənar saxlamaq üçün kifayət qədər kiçikdir.
0:40 Bu maşında, "comprehension" təxminən otuz üç millisaniyə çəkdi. NumPy bir saniyədən az çəkdi. Hər ikisi CPU-da işlədi. Bu, bu iş yükü üçün faydalı sübutdur və bir proqramlaşdırma dili üçün dəhşətli bir nekrologdur. Adi döngədən başlayın.
Python döngəsi hansı işi təkrarlayır?
0:53 Python növbəti dəyəri alır, arifmetikanı yerinə yetirir və cavabı əlavə edir. Sonra bunu yenidən edir. Vurma ucuzdur. Növbəti vurmanın təşkili və ətrafındakı Python obyektlərinin idarə edilməsi, hər dəfə iş əlavə edir. Bu, test edilmiş funksiyanın faktiki "disassembly"-sidir. İterasiya, vurma və toplama baytkod təlimatları kimi görünür. Python versiyaları və tərcüməçiləri fərqli seçimlər edir.
1:14 Bu vaxtlar ekranda olan versiyaya, yəni Python üç nöqtə ona aiddir. Python siyahısı obyektlərə istinadları saxlayır, buna görə də müxtəlif növ şeylər bir siyahını paylaşa bilər. Arifmetik işimizdə hər yerdə rəqəmlər istifadə olunur. O, təkrarlanan xidmət tələb edərkən ümumi bir tənzimləmə üçün ödəniş edir. Eyni qəhvəni bir milyon dəfə sifariş etdiyinizi və hər fincan üçün yeni bir forma doldurduğunuzu təsəvvür edin. Hər fincan üçün yeni bir forma doldurduğunuzu təsəvvür edin. Qəhvə maşını yaxşıdır.
1:36 Sənədləşmə öz karyerasını inkişaf etdirib.
NumPy döngəni hara köçürür?
1:38 NumPy müqaviləni dəyişir. Bu massiv bir elan edilmiş tipə malik sabit ölçülü float dəyərləri saxlayır. Massivimiz ardıcıldır, buna görə də dəyərləri yaddaşda bir yerdə yerləşir. Görünüşlər digər düzülüşlərə malik ola bilər. Arifmetik əməliyyat hansı növ məlumat aldığını bilir. Çağırış partiyanı yerli bir əməliyyata ötürür. Tərtib edilmiş kod daxilində döngə dəyərləri hələ də ziyarət edir. O, bu iş boyunca tip haqqında bilikləri yenidən istifadə edə bilər.
2:00 Python işi təhvil verən şəxs olaraq qalır. Itamar Turner Trauring Python Speed-də fərqi izah edir. Toplu interfeyslər, yerli tətbiqlər və prosessor vektor təlimatları ayrı-ayrı şeylərdir. Funksiyanın adı çox az sübut verir.
Sürətli GPU və ya çoxsaylı CPU nüvələri deməkdir?
2:13 Bu nəticə CPU-da NumPy istifadə etdi. CuPy kimi bir GPU backend massivlər və əməliyyatlar üçün fərqli bir yer seçir. GPU almaq bu adi Python döngəsini artıq işlədiyi yerdə işləməyə davam etdirir. CPU vektor təlimatları bir neçə dəyəri birlikdə işləyə bilər. NumPy dəstəklənən kernelləri seçmək üçün mexanizmlərə malikdir. İşləmə müddətimiz mövcud xüsusiyyətləri bildirir, lakin bu ifadənin təlimatlarını izləmir. Bütün ölçülmüş qazancı vektor təlimatlarına vermək sübutu şişirtmək olardı.
2:40 GPU alış-veriş səbəti bağlı qala bilər. Alışı da ləğv edən performans düzəlişində dərin bir məmnuniyyət var. Təəssüf ki, benchmark davam edir.
Heyrətamiz sürətlənmə nə vaxt yox olur?
2:49 Səkkiz dəyərlə, "comprehension" qalib gəldi. Massiv mexanizmlərini çağırmaq kiçik işdən daha baha başa gəldi. Daha böyük hazır massivlər irəli keçdi. Təkrar sınaqlardan və qızdırılmış prosesdən istifadə etdik. Daha yeni Python versiyaları kəsişmə nöqtəsini dəyişə bilər. Sonra tətbiqin nəyə ehtiyacı olduğunu dəyişdirin. Bir Python siyahısı ilə başlayın və yeni bir Python siyahısı ilə bitirin. NumPy girişi massivə çevirməli və cavabı yenidən Python obyektlərinə çevirməlidir.
3:11 Bu addımlar, tətbiqiniz onlara ehtiyac duyursa, hesabda olmalıdır. Bir milyon dəyərdə, bu tam yol təxminən iyirmi səkkiz millisaniyə çəkdi. "Comprehension" də təxminən iyirmi səkkiz çəkdi. Dramatik üstünlüyümüz demək olar ki, bərabər oldu. Sürətli hissə gerçək idi. Üstünlük məlumatların rəqəmsal formada qalmasına icazə verməkdən asılı idi.
Benchmark-a hansı sərhədlər daxil olmalıdır?
3:28 Məlumatları izləyin. Əgər növbəti əməliyyat bir massivi qəbul edirsə, massivi saxlayın. Əgər siyahılar və massivlər arasında dəfələrlə çevirmə edirsinizsə, bu keçidləri ölçün. Bahalı bir ötürmədən əvvəl dayanmaq səhv sual üçün dəqiq rəqəmlər verir. Bu massivi vurmaq müvəqqəti nəticə yaradır. Orijinal dəyərləri əlavə etmək çıxışı yaradır. Yerli icra hələ də yaddaşa ehtiyac duyur və məlumatları hərəkət etdirir.
3:47 Bəzi əməliyyatlar çıxış buferini qəbul edir, kodunuz təhlükəsiz şəkildə yenidən istifadə edə bildikdə ayırmaları azaldır. Bir gözəl sətir bir neçə böyük bufer sifariş edə bilər. Python Speed də bu problemi qeyd edir. Ayırıcı sizin estetikanıza olduqca laqeyddir.
Tərtib edilmiş Python döngəsi də sürətli ola bilərmi?
4:00 Döngə sintaksisini saxlaya və icrasını dəyişə bilərsiniz. Numba dəstəklənən rəqəmsal Python funksiyalarını yerli koda tərtib edə bilər. Budur testimizdəki döngə tərtibçi dekoratoru ilə. Hələ də "for" deyir. Bahalı tərcüməçi yolu dəyişib. Tərtib edildikdən sonra, hazır massivlərlə bu döngə yarım millisaniyədən az çəkdi. Tərtib etmə özü bu işdə təxminən bir saniyə çəkdi. Bu quraşdırma xərci təkrar vaxtlardan kənarlaşdırıldı,
4:22 beləliklə, kiçik birdəfəlik iş fərqli müqayisəyə layiqdir. Numba-nın öz bələdçisi açıq döngələri göstərməkdən məmnundur. "Hot path"-ı tapmadan dil köçünə başlamaq profiler açmaqdan qaçmağın mürəkkəb bir yoludur. profiler açmaqdan qaçmağın mürəkkəb bir yoludur. Əvvəlcə zamanı nəyin istehlak etdiyini tapın. Şəbəkə gözləmələri, obyektin "parsing"-i və toplu arifmetika fərqli düzəlişlər tələb edir. Yerli massiv əməliyyatları hesablama və məlumat uyğun gəldikdə kömək edir.
4:43 Çağırışçınızın əslində ehtiyac duyduğu nəticəni ölçün. İndi o qısayol üçün. Sizin bir Python funksiyanız var və onun bir massivi qəbul etməsini istəyirsiniz. Vectorize adlı bir "wrapper" itkin performans düyməsi kimi səslənir. Onun sənədlərində vacib bir cümlə gözləyir.
np.vectorize əslində nə icra edir?
4:56 NumPy deyir ki, vectorize "wrapper"-i əsasən rahatlıq üçün nəzərdə tutulub. Onun tətbiqi əsasən bir "for" döngəsidir. "Wrapper" topluları qəbul edir, lakin ardıcıl elementlər üçün Python funksiyanızı çağırmağa davam edir. İnterfeys qısaldı. İcra sərhədi məşğul qaldı. Eyni dəyərlərin Python geri zəng vasitəsilə geri gəldiyini izləyin. Hazır massivlərlə bu versiya təxminən səksən yeddi millisaniyə çəkdi. O, bizim "comprehension"-dan daha yavaş idi.
5:18 Faydalı bir "broadcasting wrapper" çıxarmağa çalışdığınız hər element üçün dəqiq işi qoruya bilər. Hər element üçün dəqiq işi qoruya bilər. Toplu interfeysin arxasında olan tətbiqi yoxlayın, uyğun məlumatları faydalı formasında saxlayın və müqayisəyə çevirməni daxil edin. Uyğun məlumatları faydalı formasında saxlayın və müqayisəyə çevirməni daxil edin. Yerli, geri zəng və tərtib edilmiş döngələr zəng edənin yerindən oxşar görünə bilər. Vectorize adı saniyəölçərinizin heç vaxt imzalamadığı bir vəd verdi. Rahatlıq sizə lazım olduqda onu saxlayın. Performans üçün işləyən döngəni yoxlayın.
Kodunuzda nəyi dəyişməlisiniz?
5:41 Mənim hökmüm ölçülmüş rəqəmsal "hot path"-ı toplamaq üçün "ship it"dir. Adi döngələr artıq yaxşı işlədikdə onları saxlayın. İşin harada baş verdiyini və növbəti çağırıcının nəyə ehtiyacı olduğunu yoxlayın. Abunə olun, zəng işarəsinə vurun və fərqli bir damğa vurduğunuzu şərhlərdə mənə bildirin. Və bugünkü "diff" budur. Mən Axrisi-dən Niko. Məsuliyyətlə birləşdirin.
Mənbələr
- 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



