Перформансе Пајтона: изворне NumPy петље, повратни позиви и трошкови конверзије
Контролисани нумерички тест само за ЦПУ прати идентичне вредности кроз ЦPython петље, NumPy аритметику, Python повратни омотач и компајлирану Numba петљу.
Контролисани нумерички тест само за ЦПУ прати идентичне вредности кроз ЦPython петље, NumPy аритметику, Python повратни омотач и компајлирану Numba петљу. NumPy са спремним уносом имао је велико вођство, док је конверзија из и назад у Python листе смањила ту предност на скоро изједначење. Епизода објашњава границу извршавања и како измерити резултат који апликација захтева.
Прочитајте писано издање (енглески) ↗
Шта овај видео покрива
- ЦPython компајлира изворни код у бајткод. Поновљени рад интерпретера/објекта и типизирана изворна нумеричка петља су различити аранжмани извршавања.
- Нумеричка NumPy аритметика може предати типизиране серије компајлираним операцијама; аритметичка петља и даље постоји, а прикази могу имати неконтинуиране распореде.
- Измерите конверзију и потребну излазну репрезентацију. У овом покретању, конвертовање Python листа у низове и назад избрисало је велику предност спремног низа.
- Мала радна оптерећења могу да фаворизују обичан Python јер су фиксни трошкови позива низа битни. Прорачун са осам вредности је победио у овом мереном поређењу.
- np.vectorize је помоћни омотач који позива Python за узастопне елементе; само пакетни интерфејс не успоставља изворно нумеричко извршавање.
- Компајлиране петље у Python синтакси такође могу бити брзе. Укључите трошкове хладне компилације/подешавања када су они битни за позиваоца.
- Изворно извршавање, ЦПУ СИМД, мултинитовање и ГПУ позадине су одвојене идеје. Доступне ЦПУ функције не прате инструкције које се користе у одређеном покретању.
Преведени транскрипт
Преведено са оригиналне енглеске нарације. Доступни аудио и титлови контролисани су од стране YouTube-а.
Зашто исти ЦПУ може да заврши раније?
0:00 Мислите да Пајтону треба нови језик да би постао брз. Исти ЦПУ је покренуо нашу серију брже након што се петља померила. Где је посао отишао? Када убрзање нестаје? Која пречица враћа Пајтон назад? Ово је The Daily Diff, испод хаубе. Пратите ту пречицу. CPython је стандардна имплементација Пајтона.
0:17 Он компајлира ваш изворни код у бајткод, затим покреће те инструкције у интерпретеру. NumPy је нумеричка библиотека чији низови садрже вредности са декларисаним типом података. Његова уграђена аритметика може предати целу серију компајлираним операцијама. Узмите милион вредности у покретном зарезу, квадрирајте сваку, затим додајте оригиналну вредност. Свака верзија добија идентичне вредности и производи подударне одговоре. Вредности су довољно мале да разлике у заокруживању не утичу на резултат.
0:40 На овој машини, прорачун је трајао око тридесет три милисекунде. NumPy је трајао мање од једне. Оба су радила на ЦПУ-у. То је користан доказ за ово радно оптерећење, и ужасна посмртница за програмски језик. Почните са обичном петљом.
Какав посао понавља Python петља?
0:53 Пајтон добија следећу вредност, врши аритметику и додаје одговор. Затим то поново ради. Множење је јефтино. Припрема следећег множења и руковање Пајтон објектима око њега додаје посао сваки пут. Ово је стварна декомпилација тестиране функције. Итерација, множење и сабирање појављују се као бајткод инструкције. Пајтон верзије и интерпретери доносе различите одлуке.
1:14 Ова мерења припадају верзији на екрану, која је Пајтон три тачка десет. Пајтон листа чува референце на објекте, тако да различите врсте ствари могу делити листу. Наш аритметички задатак користи бројеве све време. Плаћа за општи аранжман док тражи понављајућу услугу. Замислите да наручујете исту кафу милион пута и попуњавате нови образац за сваку шољу. Апарат за кафу је у реду.
1:36 Папирологија је развила своју каријеру.
Где NumPy помера петљу?
1:38 NumPy мења уговор. Овај низ садржи вредности са покретним зарезом фиксне величине са једним декларисаним типом. Наш низ је непрекидан, тако да његове вредности седе заједно у меморији. Погледи могу имати друге распореде. Аритметичка операција зна какве податке прима. Позив предаје серију изворној операцији. Петља и даље посећује вредности унутар компајлираног кода. Може поново да користи знање о типу кроз тај посао.
2:00 Пајтон остаје особа која предаје посао. Итамар Тарнер Трауринг објашњава разлику у Python Speed. Пакетни интерфејси, изворне имплементације и процесорске векторске инструкције су одвојене ствари. Назив функције даје врло мало доказа.
Да ли брзо значи ГПУ или много ЦПУ језгара?
2:13 Овај резултат је користио NumPy на ЦПУ-у. ГПУ позадина као што је CuPy бира други дом за низове и операције. Куповина ГПУ-а оставља ову обичну Пајтон петљу да ради тамо где је већ радила. ЦПУ векторске инструкције могу обрадити неколико вредности заједно. NumPy има машинерију за избор подржаних језгара. Наше време извршавања извештава о доступним функцијама, али не прати ову експресију инструкције. Приписивање целог измереног добитка векторским инструкцијама би претерано продало доказе.
2:40 Колица за куповину ГПУ-а могу остати затворена. Нешто је дубоко задовољавајуће у поправци перформанси која такође поништава куповину. Нажалост, бенчмарк се наставља.
Када импресивно убрзање нестаје?
2:49 Са осам вредности, прорачун је победио. Позивање машинерије низа коштало је више од ситног посла. Већи спремни низови су преузели вођство. Користили смо поновљене пробе и загрејан процес. Новије верзије Пајтона могу променити прелазну тачку. Затим промените шта апликација треба. Почните са Пајтон листом и завршите са свежом Пајтон листом. NumPy мора да претвори унос у низ и врати одговор назад у Пајтон
3:11 објекте. Ти кораци припадају рачуну ако су вашој апликацији потребни. За милион вредности, тај комплетан пут је трајао око двадесет осам милисекунди. Прорачун је такође трајао око двадесет осам. Наше драматично вођство постало је скоро изједначење. Брзи део је био стваран. Предност је зависила од тога да се подаци задрже у свом нумеричком облику.
Које границе припадају бенчмарку?
3:28 Пратите податке. Ако следећа операција прихвата низ, задржите низ. Ако више пута конвертујете између листа и низова, измерите те прелазе. Заустављање пре скупе предаје даје тачне бројеве за погрешно питање. Множење овог низа ствара привремени резултат. Додавање оригиналних вредности ствара излаз. Изворно извршавање и даље захтева меморију и премешта податке.
3:47 Неке операције прихватају излазни бафер, смањујући алокације када ваш код може безбедно да га поново користи. Једна лепа линија може наручити неколико великих бафера. Python Speed такође указује на овај проблем. Алокатор је изузетно равнодушан према вашој естетици.
Да ли компајлирана Python петља такође може бити брза?
4:00 Такође можете задржати синтаксу петље и променити њено извршавање. Numba може компајлирати подржане нумеричке Пајтон функције у изворни код. Ево петље из нашег теста са декоратором компајлера. Још увек пише „for“. Скупи пут интерпретера се променио. Након компилације, ова петља је трајала мање од пола милисекунде са спремним низовима. Сама компилација је трајала око секунду у овом покретању. Тај трошак подешавања је искључен из поновљених мерења времена,
4:22 тако да мали једнократни посао заслужује другачије поређење. Numba-ин властити водич радо показује експлицитне петље. Покретање миграције језика пре проналажења вруће стазе је сложен начин да се избегне отварање профилера. Прво пронађите шта троши време. Мрежна чекања, парсирање објеката и групна аритметика захтевају различита решења. Операције изворног низа помажу када се прорачун и подаци уклапају.
4:43 Измерите резултат који ваш позивалац заиста треба. Сада за ту пречицу. Имате Пајтон функцију и желите да она прихвата низ. Омотач назван vectorize звучи као дугме за перформансе које недостаје. Његова документација садржи важну реченицу која чека.
Шта np.vectorize заправо извршава?
4:56 NumPy каже да је његов vectorize омотач првенствено обезбеђен ради погодности. Његова имплементација је у суштини for петља. Омотач прихвата серије, али наставља да позива вашу Пајтон функцију за узастопне елементе. Интерфејс је постао краћи. Граница извршавања је остала заузета. Погледајте исте вредности које се враћају кроз Пајтон повратни позив. Са спремним низовима, ова верзија је трајала око осамдесет седам милисекунди. Била је спорија од нашег прорачуна.
5:18 Користан омотач за емитовање може сачувати тачан рад по елементу који сте покушавали да уклоните. Проверите имплементацију иза пакетног интерфејса, чувајте компатибилне податке у њиховом корисном облику и укључите конверзију у поређење. Изворне, повратне и компајлиране петље могу изгледати слично из позиваочеве столице. Име vectorize је дало обећање које ваш штоперица никада није потписала. Задржите га када је погодност оно што вам треба. За перформансе, проверите петљу која се извршава.
Шта би требало да промените у свом коду?
5:41 Моја пресуда је SHIP IT за групно извршавање измерене нумеричке вруће стазе. Задржите обичне петље када већ добро раде. Проверите где се посао дешава и шта следећи позивалац треба. Претплатите се, притисните звоно и реците ми у коментарима да ли бисте га другачије оценили. И то је разлика за данас. Ја сам Нико из Axrisi-ја. Спајајте одговорно.
Извори
- 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



