ដំណើរការ Python៖ Native NumPy loops, callbacks និង conversion costs
ការធ្វើតេស្តលេខ CPU តែមួយដែលគ្រប់គ្រងបានអនុវត្តតាមតម្លៃដូចគ្នាតាមរយៈ CPython loops, NumPy arithmetic, Python callback wrapper និង compiled Numba loop។
ការធ្វើតេស្តលេខ CPU តែមួយដែលគ្រប់គ្រងបានអនុវត្តតាមតម្លៃដូចគ្នាតាមរយៈ CPython loops, NumPy arithmetic, Python callback wrapper និង compiled Numba loop។ NumPy ដែលត្រៀមរួចជាស្រេចមានការនាំមុខដ៏ធំ ខណៈដែលការបំប្លែងពី និងទៅជា Python lists បានកាត់បន្ថយអត្ថប្រយោជន៍នោះស្ទើរតែស្មើគ្នា។ វគ្គនេះពន្យល់ពីព្រំដែនប្រតិបត្តិ និងរបៀបវាស់ស្ទង់លទ្ធផលដែលកម្មវិធីត្រូវការ។
អានបោះពុម្ពជាលាយលក្ខណ៍អក្សរ (អង់គ្លេស) ↗
អ្វីដែលវីដេអូនេះគ្របដណ្ដប់
- CPython បំប្លែងកូដប្រភពទៅជា bytecode។ ការធ្វើការជាមួយ interpreter/object ម្តងហើយម្តងទៀត និង typed native numeric loop គឺជាការរៀបចំប្រតិបត្តិផ្សេងគ្នា។
- NumPy arithmetic លេខអាចបញ្ជូន batches ដែលបានវាយបញ្ចូលទៅប្រតិបត្តិការដែលបានបំប្លែង; arithmetic loop នៅតែមាន ហើយ views អាចមានប្លង់មិនបន្តបន្ទាប់គ្នា។
- វាស់ស្ទង់ការបំប្លែង និងការតំណាងលទ្ធផលដែលត្រូវការ។ នៅក្នុងការដំណើរការនេះ ការបំប្លែង Python lists ទៅជា arrays ហើយត្រឡប់មកវិញបានលុបបំបាត់ការនាំមុខដ៏ធំនៃ ready-array។
- ការងារតូចៗអាចពេញចិត្ត Python ធម្មតាព្រោះតម្លៃថេរនៃការហៅ array មានសារៈសំខាន់។ ការយល់ដឹងអំពីតម្លៃប្រាំបីបានឈ្នះការប្រៀបធៀបដែលបានវាស់ស្ទង់នេះ។
- np.vectorize គឺជា wrapper ងាយស្រួលដែលហៅ Python សម្រាប់ធាតុបន្តបន្ទាប់គ្នា; ចំណុចប្រទាក់ batch តែមួយមុខមិនបង្កើត native numerical execution ទេ។
- compiled Python-syntax loops ក៏អាចលឿនដែរ។ រួមបញ្ចូលតម្លៃនៃការបំប្លែង/ការរៀបចំនៅពេលដែលពួកគេសំខាន់ចំពោះអ្នកហៅ។
- Native execution, CPU SIMD, multithreading និង GPU backends គឺជាគំនិតដាច់ដោយឡែក។ លក្ខណៈពិសេស CPU ដែលមានស្រាប់មិនតាមដានការណែនាំដែលបានប្រើក្នុងការដំណើរការជាក់លាក់ណាមួយឡើយ។
កំណត់ត្រាដែលបានបកប្រែ
បកប្រែចេញពីការនិទានដើមជាភាសាអង់គ្លេស។ សំឡេង និងចំណងជើងរងដែលមានគឺស្ថិតនៅក្រោមការគ្រប់គ្រងរបស់ YouTube។
ហេតុអ្វីបានជា CPU ដូចគ្នាអាចបញ្ចប់លឿនជាងមុន?
0:00 អ្នកគិតថា Python ត្រូវការភាសាថ្មីដើម្បីឱ្យលឿន។ CPU ដូចគ្នាបានដំណើរការ batch របស់យើងលឿនជាងមុន បន្ទាប់ពី loop បានផ្លាស់ប្តូរ។ តើការងារបានទៅណា? តើពេលណាដែលល្បឿនកើនឡើងបាត់ទៅ? តើផ្លូវកាត់ណាដែលនាំ Python ត្រឡប់មកវិញ? នេះគឺជា The Daily Diff, នៅក្រោមក្រណាត់។ ចាំមើលផ្លូវកាត់នោះ។ CPython គឺជាការអនុវត្ត Python ស្តង់ដារ។
0:17 វាបំប្លែងកូដប្រភពរបស់អ្នកទៅជា bytecode បន្ទាប់មកដំណើរការការណែនាំទាំងនោះនៅក្នុង interpreter។ NumPy គឺជាបណ្ណាល័យលេខដែល arrays របស់វាផ្ទុកតម្លៃជាមួយនឹង ប្រភេទទិន្នន័យដែលបានប្រកាស។ arithmetic ដែលបានបង្កើតឡើងរបស់វាអាចបញ្ជូន batch ទាំងមូលទៅប្រតិបត្តិការដែលបានបំប្លែង។ យកតម្លៃអណ្តែតទឹកមួយលាន ការ៉េនីមួយៗ បន្ទាប់មកបន្ថែមតម្លៃដើម។ រាល់កំណែទាំងអស់ទទួលបានតម្លៃដូចគ្នា និងបង្កើតចម្លើយដែលត្រូវគ្នា។ តម្លៃគឺតូចល្មមដើម្បីរក្សាភាពខុសគ្នានៃការបង្គត់ចេញពីការប្រណាំង។
0:40 នៅលើម៉ាស៊ីននេះ ការយល់ដឹងចំណាយពេលប្រហែលសាមសិបបីមីលីវិនាទី។ NumPy ចំណាយពេលតិចជាងមួយ។ ទាំងពីរបានដំណើរការនៅលើ CPU។ នោះគឺជាភស្តុតាងដែលមានប្រយោជន៍សម្រាប់ការងារនេះ និងជាមរណភាពដ៏អាក្រក់សម្រាប់ ភាសាសរសេរកម្មវិធី។ ចាប់ផ្តើមជាមួយនឹង loop ធម្មតា។
តើការងារអ្វីខ្លះដែល Python loop ធ្វើម្តងទៀត?
0:53 Python ទទួលបានតម្លៃបន្ទាប់ អនុវត្ត arithmetic និងបន្ថែមចម្លើយ។ បន្ទាប់មកវាម្តងទៀត។ ការគុណគឺថោក។ ការរៀបចំការគុណបន្ទាប់ និងការដោះស្រាយវត្ថុ Python នៅជុំវិញវា បន្ថែមការងាររាល់ពេល។ នេះគឺជាការបំបែកមុខងារដែលបានសាកល្បងពិតប្រាកដ។ Iteration, multiplication និង addition លេចឡើងជា bytecode instructions។ កំណែ Python និង interpreters ធ្វើការជ្រើសរើសខុសគ្នា។
1:14 ពេលវេលាទាំងនេះជាកម្មសិទ្ធិរបស់កំណែនៅលើអេក្រង់ ដែលជា Python 3.10។ Python list ផ្ទុក references ទៅ objects ដូច្នេះប្រភេទផ្សេងៗនៃវត្ថុអាច ចែករំលែក list មួយ។ ការងារ arithmetic របស់យើងប្រើលេខទាំងស្រុង។ វាបង់ថ្លៃសម្រាប់ការរៀបចំទូទៅ ខណៈពេលដែលស្នើសុំសេវាកម្មម្តងហើយម្តងទៀត។ ស្រមៃមើលការបញ្ជាទិញកាហ្វេដូចគ្នាមួយលានដង និងបំពេញទម្រង់ថ្មី សម្រាប់ពែងនីមួយៗ។ ម៉ាស៊ីនកាហ្វេគឺល្អ។
1:36 ឯកសារបានបង្កើតអាជីពផ្ទាល់ខ្លួនរបស់វា។
តើ NumPy ផ្លាស់ប្តូរ loop ទៅទីណា?
1:38 NumPy ផ្លាស់ប្តូរកិច្ចសន្យា។ array នេះផ្ទុកតម្លៃអណ្តែតទឹកទំហំថេរជាមួយនឹងប្រភេទដែលបានប្រកាសមួយ។ array របស់យើងគឺបន្តបន្ទាប់គ្នា ដូច្នេះតម្លៃរបស់វាស្ថិតនៅជាមួយគ្នាក្នុង memory។ Views អាចមានប្លង់ផ្សេងទៀត។ ប្រតិបត្តិការ arithmetic ដឹងថាទិន្នន័យប្រភេទណាដែលវាកំពុងទទួល។ ការហៅបានបញ្ជូន batch ទៅ native operation។ loop នៅតែចូលមើលតម្លៃនៅខាងក្នុង compiled code។ វាអាចប្រើចំណេះដឹងអំពីប្រភេទម្តងហើយម្តងទៀតលើការងារនោះ។
2:00 Python នៅតែជាអ្នកដែលប្រគល់ការងារ។ Itamar Turner Trauring ពន្យល់ពីភាពខុសគ្នានៅក្នុង Python Speed។ ចំណុចប្រទាក់ Batch, native implementations និង processor vector instructions គឺជា របស់ដាច់ដោយឡែក។ ឈ្មោះមុខងារផ្តល់ភស្តុតាងតិចតួចណាស់។
តើលឿនមានន័យថា GPU ឬ CPU cores ច្រើន?
2:13 លទ្ធផលនេះបានប្រើ NumPy នៅលើ CPU។ GPU backend ដូចជា CuPy ជ្រើសរើសកន្លែងផ្សេងសម្រាប់ arrays និង operations។ ការទិញ GPU ធ្វើឱ្យ loop Python ធម្មតានេះដំណើរការនៅកន្លែងដែលវាបានដំណើរការរួចហើយ។ CPU vector instructions អាចដំណើរការតម្លៃជាច្រើនជាមួយគ្នា។ NumPy មានយន្តការសម្រាប់ការជ្រើសរើស kernels ដែលគាំទ្រ។ runtime របស់យើងរាយការណ៍ពីលក្ខណៈពិសេសដែលមាន ប៉ុន្តែមិនតាមដាន ការណែនាំនៃការបញ្ចេញមតិនេះទេ។ ការផ្តល់អត្ថប្រយោជន៍ដែលបានវាស់វែងទាំងមូលដល់ vector instructions នឹង បំផ្លើសភស្តុតាង។
2:40 រទេះទិញទំនិញ GPU អាចនៅបិទជិត។ មានអ្វីដែលពេញចិត្តយ៉ាងខ្លាំងអំពីការកែសម្រួលដំណើរការដែលក៏បានលុបចោលការ ទិញផងដែរ។ ជាអកុសល ការវាស់ស្ទង់បន្ត។
តើពេលណាដែលល្បឿនកើនឡើងគួរឱ្យចាប់អារម្មណ៍បាត់បង់?
2:49 ជាមួយនឹងតម្លៃប្រាំបី ការយល់ដឹងបានឈ្នះ។ ការហៅ array machinery ចំណាយច្រើនជាងការងារតូចតាច។ arrays ដែលត្រៀមរួចជាស្រេចធំជាងបាននាំមុខ។ យើងបានប្រើការសាកល្បងម្តងហើយម្តងទៀត និងដំណើរការដែលបានកំដៅ។ ការបង្កើត Python ថ្មីអាចផ្លាស់ប្តូរការផ្លាស់ប្តូរ។ បន្ទាប់មកផ្លាស់ប្តូរអ្វីដែលកម្មវិធីត្រូវការ។ ចាប់ផ្តើមជាមួយនឹង Python list ហើយបញ្ចប់ជាមួយនឹង Python list ថ្មី។ NumPy ត្រូវតែបំប្លែងធាតុបញ្ចូលទៅជា array ហើយបំប្លែងចម្លើយត្រឡប់ទៅជាវត្ថុ Python
3:11 វិញ។ ជំហានទាំងនោះជាផ្នែកនៃវិក្កយបត្រប្រសិនបើកម្មវិធីរបស់អ្នកត្រូវការពួកគេ។ ក្នុងតម្លៃមួយលាន ផ្លូវពេញលេញនោះចំណាយពេលប្រហែលម្ភៃប្រាំបីមីលីវិនាទី។ ការយល់ដឹងចំណាយពេលប្រហែលម្ភៃប្រាំបីផងដែរ។ ការនាំមុខដ៏គួរឱ្យចាប់អារម្មណ៍របស់យើងបានក្លាយជាស្ទើរតែស្មើគ្នា។ ផ្នែកដែលលឿនគឺពិតប្រាកដ។ អត្ថប្រយោជន៍អាស្រ័យលើការអនុញ្ញាតឱ្យទិន្នន័យស្ថិតក្នុងទម្រង់លេខរបស់វា។
តើព្រំដែនណាខ្លះដែលជាផ្នែកនៃការវាស់ស្ទង់?
3:28 តាមដានទិន្នន័យ។ ប្រសិនបើប្រតិបត្តិការបន្ទាប់ទទួលយក array សូមរក្សា array នោះ។ ប្រសិនបើអ្នកបំប្លែងម្តងហើយម្តងទៀតរវាង lists និង arrays វាស់ស្ទង់ការផ្លាស់ប្តូរទាំងនោះ។ ការឈប់មុនពេលការផ្ទេរថ្លៃដើមផ្តល់លេខត្រឹមត្រូវសម្រាប់ សំណួរខុស។ ការគុណ array នេះបង្កើតលទ្ធផលបណ្តោះអាសន្ន។ ការបន្ថែមតម្លៃដើមបង្កើតលទ្ធផល។ Native execution នៅតែត្រូវការ memory និងផ្លាស់ប្តូរទិន្នន័យ។
3:47 ប្រតិបត្តិការខ្លះទទួលយក output buffer កាត់បន្ថយការបែងចែកនៅពេលដែលកូដរបស់អ្នកអាច ប្រើវាឡើងវិញដោយសុវត្ថិភាព។ បន្ទាត់ដ៏ស្រស់ស្អាតមួយអាចបញ្ជាទិញ buffers ធំៗជាច្រើន។ Python Speed ក៏លើកឡើងពីបញ្ហានេះដែរ។ allocator គឺមិនខ្វល់ខ្វាយគួរឱ្យកត់សម្គាល់ចំពោះសោភ័ណភាពរបស់អ្នកទេ។
តើ compiled Python loop ក៏អាចលឿនដែរឬទេ?
4:00 អ្នកក៏អាចរក្សា loop syntax និងផ្លាស់ប្តូរប្រតិបត្តិការរបស់វា។ Numba អាចបំប្លែងមុខងារ Python លេខដែលគាំទ្រទៅជា native code។ នេះគឺជា loop ពីការធ្វើតេស្តរបស់យើងជាមួយនឹង compiler decorator របស់វា។ វានៅតែនិយាយថា for។ ផ្លូវ interpreter ដែលថ្លៃដើមបានផ្លាស់ប្តូរ។ បន្ទាប់ពីការបំប្លែង loop នេះចំណាយពេលតិចជាងកន្លះមីលីវិនាទីជាមួយនឹង ready arrays។ ការបំប្លែងខ្លួនវាចំណាយពេលប្រហែលមួយវិនាទីក្នុងការដំណើរការនេះ។ តម្លៃនៃការរៀបចំនោះត្រូវបានដកចេញពីពេលវេលាដែលបានធ្វើម្តងទៀត
4:22 ដូច្នេះការងារតែមួយមុខតូចមួយសមនឹងទទួលបានការប្រៀបធៀបផ្សេងគ្នា។ មគ្គុទ្ទេសក៍របស់ Numba ខ្លួនវាសប្បាយរីករាយក្នុងការបង្ហាញ loops ជាក់លាក់។ ការចាប់ផ្តើមការផ្លាស់ប្តូរភាសាមុនពេលស្វែងរក hot path គឺជាវិធីសាស្ត្រស្មុគស្មាញមួយដើម្បី ជៀសវាងការបើក profiler។ ដំបូងរកមើលអ្វីដែលស៊ីពេលវេលា។ ការរង់ចាំបណ្តាញ ការវិភាគវត្ថុ និង bulk arithmetic ត្រូវការការជួសជុលផ្សេងគ្នា។ ប្រតិបត្តិការ native array ជួយនៅពេលដែលការគណនា និងទិន្នន័យសម។
4:43 វាស់ស្ទង់លទ្ធផលដែលអ្នកហៅពិតជាត្រូវការ។ ឥឡូវនេះសម្រាប់ផ្លូវកាត់នោះ។ អ្នកមានមុខងារ Python ហើយចង់ឱ្យវាទទួលយក array។ Wrapper ឈ្មោះ vectorize ហាក់ដូចជាប៊ូតុងដំណើរការដែលបាត់។ ឯកសាររបស់វាមានប្រយោគសំខាន់មួយកំពុងរង់ចាំ។
តើ np.vectorize ពិតជាប្រតិបត្តិអ្វីខ្លះ?
4:56 NumPy និយាយថា vectorize wrapper របស់វាត្រូវបានផ្តល់ជូនជាចម្បងសម្រាប់ភាពងាយស្រួល។ ការអនុវត្តរបស់វាគឺសំខាន់ជា for loop។ wrapper ទទួលយក batches ប៉ុន្តែបន្តហៅមុខងារ Python របស់អ្នកសម្រាប់ ធាតុបន្តបន្ទាប់គ្នា។ ចំណុចប្រទាក់បានខ្លីជាងមុន។ ព្រំដែនប្រតិបត្តិនៅតែមមាញឹក។ មើលតម្លៃដូចគ្នាត្រឡប់មកវិញតាមរយៈ Python callback។ ជាមួយនឹង ready arrays កំណែនេះចំណាយពេលប្រហែលប៉ែតសិបប្រាំពីរមីលីវិនាទី។ វាលឿនជាងការយល់ដឹងរបស់យើង។
5:18 broadcasting wrapper ដែលមានប្រយោជន៍អាចរក្សាទុកការងារក្នុងមួយធាតុពិតប្រាកដដែលអ្នកកំពុង ព្យាយាមលុបបំបាត់។ ពិនិត្យមើលការអនុវត្តនៅពីក្រោយចំណុចប្រទាក់ batch រក្សាទិន្នន័យដែលឆបគ្នាឱ្យនៅជា ទម្រង់មានប្រយោជន៍របស់វា ហើយរួមបញ្ចូលការបំប្លែងក្នុងការប្រៀបធៀប។ Native, callback និង compiled loops អាចមើលទៅស្រដៀងគ្នាពីកៅអីអ្នកហៅ។ ឈ្មោះ vectorize បានសន្យាថា stopwatch របស់អ្នកមិនដែលចុះហត្ថលេខាទេ។ រក្សាវាទុកនៅពេលដែលភាពងាយស្រួលគឺជាអ្វីដែលអ្នកត្រូវការ។ សម្រាប់ដំណើរការ សូមពិនិត្យមើល loop ដែលដំណើរការ។
តើអ្នកគួរផ្លាស់ប្តូរអ្វីខ្លះនៅក្នុងកូដរបស់អ្នក?
5:41 ការសម្រេចចិត្តរបស់ខ្ញុំគឺ SHIP IT សម្រាប់ការបែងចែក batch នៃ numerical hot path ដែលបានវាស់វែង។ រក្សា loops ធម្មតានៅពេលដែលពួកគេដំណើរការល្អរួចហើយ។ ពិនិត្យមើលកន្លែងដែលការងារកើតឡើង និងអ្វីដែលអ្នកហៅបន្ទាប់ត្រូវការ។ ជាវ ចុចរូបកណ្ដឹង ហើយប្រាប់ខ្ញុំនៅក្នុងមតិយោបល់ប្រសិនបើអ្នកបានបោះត្រាវា ខុសគ្នា។ ហើយនោះគឺជា diff សម្រាប់ថ្ងៃនេះ។ ខ្ញុំឈ្មោះ Niko មកពី 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



