Python-ის წარმადობა: მშობლიური NumPy-ის ციკლები, ქოლბექები და კონვერტაციის ხარჯები
კონტროლირებადი CPU-მხოლოდ რიცხვითი ტესტი მიჰყვება იდენტურ მნიშვნელობებს CPython-ის ციკლებში, NumPy-ის არითმეტიკაში, Python-ის ქოლბექის შემხვევში და კომპილირებული Numba-ს ციკლში.
კონტროლირებადი CPU-მხოლოდ რიცხვითი ტესტი მიჰყვება იდენტურ მნიშვნელობებს CPython-ის ციკლებში, NumPy-ის არითმეტიკაში, Python-ის ქოლბექის შემხვევში და კომპილირებული Numba-ს ციკლში. მზა-შეყვანის NumPy-ს ჰქონდა დიდი უპირატესობა, ხოლო Python-ის სიებიდან კონვერტაციამ და უკან დაბრუნებამ ეს უპირატესობა თითქმის ნულამდე დაიყვანა. ეპიზოდი განმარტავს შესრულების საზღვარს და როგორ უნდა გავზომოთ ის შედეგი, რომელიც აპლიკაციას სჭირდება.
წაიკითხეთ წერილობითი გამოცემა (ინგლისური) ↗
რას მოიცავს ეს ვიდეო
- CPython კრებს წყაროს ბაიტკოდში. განმეორებითი ინტერპრეტატორის/ობიექტის მუშაობა და ტიპებთან მუშაობის მშობლიური რიცხვითი ციკლი განსხვავებული შესრულების მოწყობებია.
- რიცხვით NumPy-ის არითმეტიკას შეუძლია ტიპებთან მუშაობის პარტიები გადასცეს კომპილირებულ ოპერაციებს; არითმეტიკული ციკლი მაინც არსებობს, და ხედებს შეიძლება ჰქონდეთ არაკონტიგუალური განლაგება.
- გაზომეთ კონვერტაცია და საჭირო გამომავალი წარმოდგენა. ამ გაშვებაში, Python-ის სიების მასივებად გადაქცევამ და უკან დაბრუნებამ წაშალა მზა-მასივის დიდი უპირატესობა.
- მცირე სამუშაო დატვირთვებმა შეიძლება უპირატესობა მიანიჭოს ჩვეულებრივ Python-ს, რადგან ფიქსირებული მასივზე-გამოძახების ხარჯები მნიშვნელოვანია. რვა-მნიშვნელობიანმა კომპრენსიამ მოიგო ეს გაზომილი შედარება.
- np.vectorize არის მოსახერხებელი შემოხვევა, რომელიც იძახებს Python-ს თანმიმდევრული ელემენტებისთვის; მხოლოდ პარტიული ინტერფეისი არ აწესებს მშობლიურ რიცხვით შესრულებას.
- კომპილირებული Python-ის სინტაქსის ციკლები ასევე შეიძლება იყოს სწრაფი. ჩართეთ ცივი კომპილაციის/დაყენების ხარჯები, როდესაც ისინი მნიშვნელოვანია გამომძახებლისთვის.
- მშობლიური შესრულება, CPU SIMD, მრავალნაკადოვნება და GPU ბექენდები ცალკეული იდეებია. ხელმისაწვდომი CPU ფუნქციები არ მიჰყვება კონკრეტულ გაშვებაში გამოყენებულ ინსტრუქციებს.
ნათარგმნი ტრანსკრიპტი
ნათარგმნია ორიგინალური ინგლისური ნარატივიდან. ხელმისაწვდომი აუდიო და სუბტიტრები კონტროლდება YouTube-ის მიერ.
რატომ შეუძლია იგივე CPU-ს უფრო ადრე დაასრულოს?
0:00 ფიქრობთ, რომ Python-ს ახალი ენა სჭირდება, რომ სწრაფი გახდეს. იგივე CPU-მ ჩვენი პარტია უფრო სწრაფად გაუშვა, მას შემდეგ რაც ციკლი გადავიდა. სად წავიდა სამუშაო? როდის ქრება აჩქარება? რომელი მალსახმობი აბრუნებს Python-ს? ეს არის The Daily Diff, კულისებს მიღმა. დააკვირდით ამ მალსახმობს. CPython არის სტანდარტული Python-ის იმპლემენტაცია.
0:17 ის თქვენს წყაროს ბაიტკოდში კრებს, შემდეგ კი ამ ინსტრუქციებს ინტერპრეტატორში უშვებს. NumPy არის რიცხვითი ბიბლიოთეკა, რომლის მასივები აცხადებს მონაცემთა ტიპს. მისი ჩაშენებული არითმეტიკა მთელ პარტიას კომპილირებულ ოპერაციებს გადასცემს. აიღეთ მილიონი მცოცავწერტილიანი მნიშვნელობა, აამაღლეთ თითოეული კვადრატში, შემდეგ დაამატეთ ორიგინალი მნიშვნელობა. ყველა ვერსია იღებს იდენტურ მნიშვნელობებს და აწარმოებს შესაბამის პასუხებს. მნიშვნელობები საკმარისად მცირეა იმისთვის, რომ დამრგვალების განსხვავებები არ მოხვდეს რბოლაში.
0:40 ამ მანქანაზე, კომპრენსიას დაახლოებით ოცდაცამეტი მილიწამი დასჭირდა. NumPy-ს ერთ მილიწამზე ნაკლები დასჭირდა. ორივე CPU-ზე მუშაობდა. ეს სასარგებლო მტკიცებულებაა ამ სამუშაო დატვირთვისთვის, და საშინელი ნეკროლოგი პროგრამირების ენისთვის. დავიწყოთ ჩვეულებრივი ციკლით.
რა სამუშაოს იმეორებს Python-ის ციკლი?
0:53 Python იღებს შემდეგ მნიშვნელობას, ასრულებს არითმეტიკას და ამატებს პასუხს. შემდეგ ის ამას ისევ აკეთებს. გამრავლება იაფია. შემდეგი გამრავლების მოწყობა და მის გარშემო არსებული Python ობიექტების დამუშავება, ამატებს სამუშაოს ყოველ ჯერზე. ეს არის შემოწმებული ფუნქციის რეალური დისასემბლი. იტერაცია, გამრავლება და დამატება ბაიტკოდის ინსტრუქციებად ჩანს. Python-ის ვერსიები და ინტერპრეტატორები სხვადასხვა არჩევანს აკეთებენ.
1:14 ეს დროები ეკუთვნის ეკრანზე გამოსახულ ვერსიას, რომელიც Python სამი წერტილი ათია. Python-ის სია ინახავს ობიექტების მითითებებს, ასე რომ სხვადასხვა სახის ნივთებს შეუძლიათ გაიზიარონ სია. ჩვენი არითმეტიკული დავალება მთლიანად რიცხვებს იყენებს. ის იხდის საერთო მოწყობისთვის, ხოლო მოითხოვს განმეორებით მომსახურებას. წარმოიდგინეთ, რომ მილიონჯერ შეუკვეთეთ იგივე ყავა და ყოველი ჭიქისთვის ახალ ფორმას ავსებთ. ყავის მანქანა კარგადაა.
1:36 დოკუმენტაციამ საკუთარი კარიერა განავითარა.
სად გადააქვს NumPy ციკლი?
1:38 NumPy ცვლის კონტრაქტს. ეს მასივი ინახავს ფიქსირებული ზომის მცოცავწერტილიან მნიშვნელობებს ერთი დეკლარირებული ტიპით. ჩვენი მასივი კონტიგუურია, ასე რომ მისი მნიშვნელობები მეხსიერებაში ერთად ზის. ხედებს შეიძლება ჰქონდეთ სხვა განლაგება. არითმეტიკულმა ოპერაციამ იცის, რა სახის მონაცემებს იღებს. გამოძახება პარტიას მშობლიურ ოპერაციას გადასცემს. ციკლი მაინც სტუმრობს მნიშვნელობებს კომპილირებული კოდის შიგნით. მას შეუძლია ტიპის ცოდნის ხელახლა გამოყენება ამ სამუშაოს მასშტაბით.
2:00 Python რჩება იმ ადამიანად, ვინც სამუშაოს გადასცემს. Itamar Turner Trauring განმარტავს განსხვავებას Python Speed-ში. პარტიული ინტერფეისები, მშობლიური იმპლემენტაციები და პროცესორის ვექტორული ინსტრუქციები ცალკეული რამეებია. ფუნქციის სახელი ძალიან ცოტა მტკიცებულებას იძლევა.
სწრაფი ნიშნავს GPU-ს თუ ბევრ CPU ბირთვს?
2:13 ეს შედეგი იყენებდა NumPy-ს CPU-ზე. GPU ბექენდი, როგორიცაა CuPy, ირჩევს სხვა ადგილს მასივებისთვის და ოპერაციებისთვის. GPU-ის ყიდვა ამ ჩვეულებრივ Python-ის ციკლს იქ ტოვებს, სადაც ის უკვე მუშაობდა. CPU ვექტორულ ინსტრუქციებს შეუძლიათ ერთად რამდენიმე მნიშვნელობის დამუშავება. NumPy-ს აქვს მექანიზმები მხარდაჭერილი ბირთვების არჩევისთვის. ჩვენი გაშვების დრო აფიქსირებს ხელმისაწვდომ ფუნქციებს, მაგრამ არ აკონტროლებს ამ გამოსახულების ინსტრუქციებს. მთელი გაზომილი მოგების ვექტორულ ინსტრუქციებზე მიცემა გადააჭარბებდა მტკიცებულებას.
2:40 GPU-ის საყიდლების კალათა შეიძლება დახურული დარჩეს. რაღაც ღრმად დამაკმაყოფილებელია შესრულების გამოსწორებაში, რომელიც ასევე აუქმებს შესყიდვას. სამწუხაროდ, ბენჩმარკი გრძელდება.
როდის ქრება შთამბეჭდავი აჩქარება?
2:49 რვა მნიშვნელობით, კომპრენსიამ მოიგო. მასივის მექანიზმების გამოძახება უფრო ძვირი დაჯდა, ვიდრე პატარა სამუშაო. უფრო დიდი მზა მასივები წინ წავიდნენ. ჩვენ გამოვიყენეთ განმეორებითი ცდები და გახურებული პროცესი. უფრო ახალმა Python-ის აგებულებამ შეიძლება შეცვალოს კროსოვერი. შემდეგ შეცვალეთ ის, რაც აპლიკაციას სჭირდება. დაიწყეთ Python-ის სიით და დაასრულეთ ახალი Python-ის სიით. NumPy-მ უნდა გადაიყვანოს შეყვანა მასივად და პასუხი ისევ Python-ის
3:11 ობიექტებად აქციოს. ეს ნაბიჯები უნდა იყოს ანგარიშზე, თუ თქვენს აპლიკაციას ისინი სჭირდება. მილიონ მნიშვნელობაზე, ამ სრულ გზას დაახლოებით ოცდარვა მილიწამი დასჭირდა. კომპრენსიასაც დაახლოებით ოცდარვა დასჭირდა. ჩვენი დრამატული უპირატესობა თითქმის ფრედ იქცა. სწრაფი ნაწილი რეალური იყო. უპირატესობა დამოკიდებული იყო მონაცემების რიცხვით ფორმაში შენარჩუნებაზე.
რომელი საზღვრები ეკუთვნის ბენჩმარკს?
3:28 მიჰყევით მონაცემებს. თუ შემდეგი ოპერაცია იღებს მასივს, შეინახეთ მასივი. თუ სიებსა და მასივებს შორის განმეორებით კონვერტირებას აკეთებთ, გაზომეთ ეს გადასვლები. ძვირადღირებულ გადაცემამდე გაჩერება არასწორი კითხვისთვის ზუსტ რიცხვებს იძლევა. ამ მასივის გამრავლება ქმნის დროებით შედეგს. ორიგინალური მნიშვნელობების დამატება ქმნის გამომავალს. მშობლიურ შესრულებას მაინც სჭირდება მეხსიერება და მონაცემების გადატანა.
3:47 ზოგიერთი ოპერაცია იღებს გამომავალ ბუფერს, ამცირებს მეხსიერების გამოყოფას, როდესაც თქვენს კოდს შეუძლია უსაფრთხოდ გამოიყენოს იგი. ერთ ლამაზ ხაზს შეუძლია რამდენიმე დიდი ბუფერის შეკვეთა. Python Speed ამ პრობლემასაც ახსენებს. ალოკატორი საოცრად გულგრილია თქვენი ესთეტიკის მიმართ.
შეიძლება თუ არა კომპილირებული Python-ის ციკლიც იყოს სწრაფი?
4:00 თქვენ ასევე შეგიძლიათ შეინარჩუნოთ ციკლის სინტაქსი და შეცვალოთ მისი შესრულება. Numba-ს შეუძლია მხარდაჭერილი რიცხვითი Python ფუნქციების კომპილაცია მშობლიურ კოდში. აქ არის ციკლი ჩვენი ტესტიდან მისი კომპილატორის დეკორატორით. ის მაინც ამბობს "for". ძვირადღირებული ინტერპრეტატორის გზა შეიცვალა. კომპილაციის შემდეგ, ამ ციკლს მზა მასივებით ნახევარ მილიწამზე ნაკლები დასჭირდა. კომპილაციას თავად დაახლოებით ერთი წამი დასჭირდა ამ გაშვებაში. ეს დაყენების ხარჯი გამორიცხული იყო განმეორებითი დროებიდან,
4:22 ასე რომ, პატარა ერთჯერადი სამუშაო სხვა შედარებას იმსახურებს. Numba-ს საკუთარი სახელმძღვანელო სიამოვნებით აჩვენებს მკაფიო ციკლებს. ენის მიგრაციის დაწყება ცხელი გზის პოვნამდე პროფაილერის გახსნის თავიდან აცილების დახვეწილი გზაა. ჯერ იპოვეთ, რა მოიხმარს დროს. ქსელის ლოდინი, ობიექტების გაანალიზება და ნაყარი არითმეტიკა სხვადასხვა გამოსწორებას მოითხოვს. მშობლიური მასივის ოპერაციები დაგეხმარებათ, როდესაც გაანგარიშება და მონაცემები ემთხვევა. გაზომეთ ის შედეგი, რომელიც თქვენს გამომძახებელს რეალურად სჭირდება.
4:43 ახლა კი ამ მალსახმობისთვის. თქვენ გაქვთ Python ფუნქცია და გსურთ, რომ მან მიიღოს მასივი. wrapper სახელად vectorize ჟღერს როგორც დაკარგული წარმადობის ღილაკი. მის დოკუმენტაციას მნიშვნელოვანი წინადადება ელოდება. NumPy ამბობს, რომ მისი vectorize wrapper ძირითადად მოხერხებულობისთვის არის განკუთვნილი.
რას ასრულებს np.vectorize სინამდვილეში?
4:56 მისი იმპლემენტაცია არსებითად for ციკლია. wrapper იღებს პარტიებს, მაგრამ განაგრძობს თქვენი Python ფუნქციის გამოძახებას თანმიმდევრული ელემენტებისთვის. ინტერფეისი დამოკლდა. შესრულების საზღვარი დაკავებული დარჩა. უყურეთ იგივე მნიშვნელობების დაბრუნებას Python-ის ქოლბექის მეშვეობით. მზა მასივებით, ამ ვერსიას დაახლოებით ოთხმოცდაშვიდი მილიწამი დასჭირდა. ის ჩვენს კომპრენსიაზე ნელი იყო. სასარგებლო მაუწყებლობის wrapper-ს შეუძლია შეინარჩუნოს ზუსტი თითოეული ელემენტის სამუშაო, რომლის
5:18 მოშორებასაც ცდილობდით. შეამოწმეთ იმპლემენტაცია პარტიული ინტერფეისის მიღმა, შეინახეთ თავსებადი მონაცემები მის სასარგებლო ფორმაში, და ჩართეთ კონვერტაცია შედარებაში. მშობლიური, ქოლბექის და კომპილირებული ციკლები შეიძლება მსგავსად გამოიყურებოდეს გამომძახებლის სავარძლიდან. სახელმა vectorize დაპირება მისცა, რომელიც თქვენს წამზომს არასოდეს მოუწერია ხელი. შეინახეთ იგი, როდესაც მოხერხებულობა გჭირდებათ. წარმადობისთვის, შეამოწმეთ ციკლი, რომელიც მუშაობს. ჩემი ვერდიქტია SHIP IT გაზომილი რიცხვითი ცხელი გზის დაჯგუფებისთვის.
რა უნდა შეცვალოთ თქვენს კოდში?
5:41 შეინარჩუნეთ ჩვეულებრივი ციკლები, როდესაც ისინი უკვე კარგად მუშაობენ. შეამოწმეთ, სად ხდება სამუშაო და რა სჭირდება შემდეგ გამომძახებელს. გამოიწერეთ, დააჭირეთ ზარს და მითხარით კომენტარებში, სხვაგვარად დალუქავდით თუ არა მას. და ეს არის დღევანდელი განსხვავება. მე ვარ ნიკო 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



