📝

Draft article

This draft is visible to admins and superusers only. Sign in with an authorized account.

← Maqolalarga qaytish
July 7, 2026
5 daqiqa o'qish

GPU qachon o'zini oqlaydi: parametr qidiruvi roofline'i — sarlavhadagi 167x aslida 27x algoritm karra 6.2x apparat

GPU qachon o'zini oqlaydi: parametr qidiruvi roofline'i — sarlavhadagi 167x aslida 27x algoritm karra 6.2x apparat
#algotrading
#backtest
#unumdorlik
#gpu
#roofline
#optimallashtirish
Part 9 of 10 · Collection
High-Performance Backtest Engines

"Illyuziyalarsiz backtestlar" turkumining bir qismi.

Tezlik narvoni ataylab ko'ngil to'lmaydigan nuqtada tugagan edi. Biz 80 kombinatsiyali parametr qidiruvini (parameter sweep) noutbuk CPUsida 69.9 soniyalik pandas'dan 0.23 soniyalik parallel numba'gacha olib tushdik — o'lchangan 298x — va shundan keyin GPU yetishmayotgan pog'ona emas, deb ta'kidladik. Izohlar bo'limi buni jim qabul qilmadi va haqli edi. "Yetishmayotgan pog'ona emas" — bu bitta ish yuki va bitta hajm haqidagi da'vo. Bu tabiat qonuni emas. Shu bois ushbu maqola halollik bilan ish tutadi va GPUni sinov stoliga qo'yadi.

Natija hukm emas — egri chiziq. GPUning CPUdan ustunligi slaydga bosib qo'yiladigan yakka raqam emas; u har bir chaqiruvda GPUga qancha ish topshirishingizning funksiyasi. Ko'p taymfreymli indikatorlarni oldindan hisoblash bosqichimizda GPUning CPU dvigateliga nisbatan tezlanishi har chaqiruvda bitta parametr kombinatsiyasi so'ralganda 54.5x dan, bir yo'la 61 tasi so'ralganda 359.6x gacha boradi. Kernel o'sha, ma'lumotlar o'sha, apparat o'sha — o'zgargan yagona narsa paket (batch) hajmi. Shu raqamlardan birini e'lon qilib, ikkinchisini yashiradigan benchmark GPUni o'lchamaydi — u sarlavha tanlaydi.

Va hatto 359.6x ham ko'ringanicha emas. Uni qavatlab ochsangiz, ko'p taymfreymli katta sarlavhadagi 167x quyidagiga parchalanadi: 27x algoritm — CPUni ham 27x tezlashtiradigan qayta yozish — karra 6.2x haqiqiy apparat. 27x ni GPU qilgani yo'q. Uni matematika qildi. Ushbu maqola ana shu ikkisini farqlash haqida, chunki ularni aralashtirib yuborish — bepul git commit hal qiladigan muammoni yechish uchun $2,000 lik videokarta sotishning yo'li.

Manba: quyidagi barcha raqamlar Apple M2 Max'da o'lchangan — Metal GPUda MLX orqali fp32, unga qarshi o'n ikki CPU oqimida fp64 numba — bizning engine_multitf_gpu.py va bench_param_sweep.py benchmark skriptlarimizdan olingan bo'lib, ularning har biri GPU va CPU yo'llari aynan bir xil savdolarni berishini tasdiqlovchi ekvivalentlik tekshiruvi bilan qo'riqlanadi. Bu maqolaning ochiq hamroh maqolasi yo'q — hujjat skriptlarning o'zi.

Savol — benchmark emas, roofline

Roofline diagrammasi: o'ngda tekis hisoblash shifti, chapda tik xotira o'tkazuvchanligi qiyaligi va ustama hukmron burchakdan tizma nuqtasi tomon qiyalik bo'ylab ko'tarilayotgan paket nuqtasi

"GPU qancha tezroq" degan savolning yagona javobi yo'qligining sababi — roofline modeli (Williams, Waterman & Patterson, 2009). Protsessorning erishiladigan unumdorligi bir vaqtning o'zida ikkita shift bilan cheklangan: eng yuqori hisoblash quvvati (FLOP/s) belgilaydigan tekis shift va xotira o'tkazuvchanligini arifmetik intensivlikka — har bir ko'chirilgan baytga to'g'ri keladigan foydali amallar soniga — ko'paytirishdan hosil bo'ladigan qiya shift. Har baytiga arzon ish qiya shift ostida yashaydi va xotira o'tkazuvchanligi bilan chegaralangan (bandwidth-bound); har baytiga boy ish tekis shiftga yetib boradi va hisob bilan chegaralangan (compute-bound). GPUning tekis shifti CPUnikidan osmono'par balandlikda turadi, lekin uning qiya shifti va — eng muhimi — har chaqiruvdagi qat'iy narxi kichrayish tomon bunchalik silliq masshtablanmaydi.

Parametr qidiruvida esa diagrammaning chap tomonida uchinchi had hukmronlik qiladi: ishga tushirish va uzatish ustamasi (overhead). Har bir GPU chaqiruvi taxminan qat'iy narx to'laydi — kernelni yuborish, kirish ma'lumotlarini (Apple Silicon'da yagona bo'lsa-da, baribir tekin bo'lmagan) xotira chegarasi orqali ko'chirish, natijalarni qaytarib olish. BB ta kombinatsiyadan iborat paketning bajarilish vaqtini quyidagicha modellashtiramiz:

Tgpu(B)=O+bB,Tcpu(B)=aBT_{\text{gpu}}(B) = O + b\,B, \qquad T_{\text{cpu}}(B) = a\,B

bu yerda OO — o'sha qat'iy ustama, bb — GPUning har bir kombinatsiya uchun marjinal narxi, aa — CPUniki. Tezlanish esa

S(B)=aBO+bB  B  ab.S(B) = \frac{a\,B}{O + b\,B} \;\xrightarrow{B \to \infty}\; \frac{a}{b}.

Shu bitta kasr butun maqolani tushuntiradi. Kichik BB da maxrajdagi OO nisbatni ezib tashlaydi — siz GPUni uyg'otish uchun pul to'ladingiz, lekin undan deyarli foydalanmadingiz. BB o'sgani sari OO ko'proq kombinatsiyalar orasida amortizatsiya bo'ladi va tezlanish o'z asimptotasi a/ba/bhaqiqiy apparat nisbati tomon ko'tariladi. Yarimlik nuqtasi B=O/bB = O/b da joylashgan: bu paket fazosidagi "tizma nuqtasi" (ridge point) bo'lib, GPU o'z imkoniyatining hech bo'lmaganda yarmiga chiqishi uchun qidiruvingiz qanchalik keng bo'lishi kerakligini aytadi. Bir necha o'nlab kombinatsiyali qidiruv bu tizmadan ancha chapda turadi. Minglab kombinatsiyali qidiruv esa GPU nihoyat o'z shiftini oqlaydigan tekis qismda o'tiradi.

Demak, to'g'ri savol hech qachon "GPU tezroqmi" emas. To'g'ri savol: "mening qidiruvim tizmadan o'ngdami va har bir kombinatsiyaga to'g'ri keladigan ish u yerga yetganda tekis shiftga chiqadigan darajada hisob bilan chegaralanganmi". Ikkalasi ham rost bo'lishi shart. Maqolaning qolgan qismi bu chegaralar amalda qayerga tushishini o'lchaydi.

Bitta taymfreym bo'yicha hukm: GPU zo'rg'a yutadi

Bir xil 80 kombinatsiyali bitta taymfreymli qidiruv uchun ikkita ustun: soniyasiga 246 kombinatsiya beradigan o'n ikki yadroli CPU to'plami yonida 779 beradigan GPU — jarlik emas, kamtarona 3.2x farq

Tezlik narvoni ishlatgan ish yukidan boshlaylik: bitta taymfreymli HMA/HMA3 qidiruvi, 150,000 bar ustida 80 ta kombinatsiya. Biz o'sha narvonga oltinchi pog'ona qo'shdik — M5: indikatorlar MLX orqali Apple GPUsida, savdolar esa avvalgidek CPUda ajratib olinadi. Isitib olingan holatda, uch yurgizishning eng yaxshisi, ekvivalentlik tekshiruvi yashil:

Usul Vaqt pandas'ga nisbatan Kombinatsiya/s
M0 pandas + sikl 287.08s 1.0x 0.3
M2 numba (1 yadro) 2.02s 142x 39.7
M4 mp + numba (12 yadro) 0.33s 883x 245.9
M5 MLX GPU (fp32) 0.10s 2796x 779.2

Sodda ketma-ket bazaviy chiziqqa (baseline) nisbatan GPU qahramonona ko'rinadi — 2,796x. Lekin bu halol odam qilmaydigan taqqoslash: unda yaxshi GPU realizatsiyasi eng yomon CPU realizatsiyasiga qarshi qo'yiladi. GPUni amalda ishlatiladigan CPU bilan bir safga qo'ying — o'sha kernel barcha o'n ikki yadroda, ya'ni M4 — va yutuq hushyor 3.2x ga tushib qoladi (soniyasiga 779 kombinatsiya 246 ga qarshi). Butun boshli videokarta, qidiruvning hammasini o'zi yuritib, o'n ikki yadroli CPU to'plamini bor-yo'g'i uch barobar ortda qoldiradi.

3.2x — arzimagan narsa emas. Lekin GPU shu sabab bilan sotib olinmaydi ham. Va bu shunchalik tor qidiruv uchun roofline aynan bashorat qilgan narsa: 80 kombinatsiya — tizmadan chapda. Qat'iy ishga tushirish-va-uzatish ustamasi OO 0.10 soniyalik ish ichida hali ham sezilarli ulush, shuning uchun a/ba/b asimptotasiga hech qachon yetib bormaymiz. Yomoni, har kombinatsiya narxining bir qismi — O(n) savdo ajratish o'tishi bo'lib, biz uni ataylab CPUda qoldirdik — bu GPU umuman tezlashtira olmaydigan had (nega bunday ekani keyingi bo'limda). Shu hajmdagi bitta taymfreymli tadqiqot sikli uchun tezlik narvonining asl hukmi kuchda qoladi: GPU yetishmayotgan pog'ona emas. Parallel numba sizni allaqachon 0.23–0.33 soniyaga olib chiqqan edi va uni 0.10 ga qisqartirish tadqiqotchini to'siqdan chiqaradigan narsa emas. Chiqaradigani — qidiruv atrofidagi orkestratsiya.

Bu hukmdagi qiziq so'z — shu hajmdagi. Paket o'qi bo'ylab o'ngga suriling, hikoya o'zgaradi.

Xarajat aslida qayerda yotibdi

Paketni kattalashtirishdan oldin, aslida nimaga pul to'layotganimizga qaraylik, chunki roofline sizni faqat qimmat qism hisob bilan chegaralangan bo'lsagina mukofotlaydi. Qidiruvni profillang — va uning deyarli hammasi bitta narsa: vaznli harakatlanuvchi o'rtacha (WMA) konvolyutsiyalari. HMA — bu uchta WMA; HMA3 — to'rtta; har bir kombinatsiya ularni butun qator bo'ylab qaytadan yuritadi. Savdo ajratish — ikki indikator massivini bosib o'tish, hma - hma3 ishora almashinuvlarini topish, ijrolarni qayd etish — bitta arzon O(n) o'tish. Bu qidiruv — savdo strategiyasi libosini kiyib olgan konvolyutsiya ish yuki.

Bu bo'linish — roofline'ning aynan ikkita rejimi:

  • Konvolyutsiyalar hisob bilan chegaralangan. Har bir narx ko'plab ustma-ust tushuvchi oyna yig'indilariga o'qiladi, shuning uchun arifmetik intensivlik — har bir ko'chirilgan baytga to'g'ri keladigan amallar soni — yuqori. Bu ish tekis hisoblash shiftiga intiladi, GPUda esa aynan shu shift osmono'par. Bundan ham yaxshisi, oynalar kombinatsiyalar orasida ham ustma-ust tushadi: uzunligi 40 bo'lgan WMA o'nlab kombinatsiyalarga kerak, shuning uchun paketli oldindan hisoblash uni har kombinatsiya uchun qayta hisoblamasdan bir marta hisoblab, hammasiga ulashadi. Paketlash nafaqat ishga tushirish ustamasini amortizatsiya qiladi; u yuklamalarni qayta ishlatish orqali arifmetik intensivlikni ham oshiradi. GPUga tegishli qism — mana shu.
  • Savdo ajratish xotira o'tkazuvchanligi bilan chegaralangan va shoxlangan. Bitta ketma-ket o'tish, har bir kesishmada ma'lumotga bog'liq shartli tarmoqlanishlar, qayta ishlatish deyarli yo'q. Uning arifmetik intensivligi pol darajasida, boshqaruv oqimi esa SIMD qurilmasiga dushman. Uni GPUga surish ozgina foyda berib, ko'p xarajat keltirar edi; u CPUda qoladi. Demak, u Amdahl qonuni bo'yicha bo'linishning ketma-ket dumi — GPU tezlanishi hech qachon teshib o'ta olmaydigan qat'iy pol va bitta taymfreym raqami 3.2x da to'yinganining sabablaridan biri.

Bu kernelning ko'p taymfreymli versiyasida ikkinchi, o'tkirroq saboq yashiringan va u biz tushuntirishga va'da berib kelayotgan 27x ning manbai. Ko'p taymfreymli dvigatel yuqori taymfreym HMAsini bazaviy 1 daqiqalik indeksga kelajakka qaramasdan (look-ahead'siz) tekislaydi. Buni ko'zga yaqqol ko'ringan yo'l bilan yozsangiz, bu har bir bar uchun O(length^1.5) ish — yuqori taymfreym harakatlanuvchi o'rtachalarini har bir bazaviy barda qayta hisoblash. Lekin tekislangan HMA oxirgi bir nechta yopilgan yuqori taymfreym shamlari va joriy yopilish narxidan iborat qisqa buferga nisbatan chiziqli, shuning uchun har bir bardagi butun hisob-kitob qat'iy vazn vektoriga yig'ilib qoladi: yopilgan shamlar qatori ustidan bitta conv1d, ortidan O(n) gather. Yuz millionlab ortiqcha amallar ancha qisqaroq qator ustidagi konvolyutsiyaga aylanadi.

Bu yig'ilish — apparat emas, algoritmik yutuq. Bu yaxshiroq formula. U GPUda ishlaydi va CPUda ham xuddi shunday yaxshi ishlaydi — np.correlate va gather, fp64 da. Buni mahkam yodda tuting: ko'p taymfreymli sarlavhadagi eng katta omil — umuman GPUsi yo'q mashinaga ham ochiq bo'lgan qayta yozish. Nihoyat 167x ni dekompozitsiya qilganimizda, 27x aynan shu bo'ladi.

Ustunlik paket hajmi bilan o'sadi

Paket hajmiga nisbatan GPU-CPU tezlanishining ko'tarilib boruvchi egri chizig'i: bitta kombinatsiyada 54.5x dan oltmish bittada 359.6x dan yuqorigacha, o'ttiz ikkidagi yakka pasayish esa chunk chegarasi artefakti deb izohlangan

Endi roofline bizga buyurgan o'lchov. Qimmat o'qni oling — bazaviy 1 daqiqalik qator ustida tekislangan yuqori taymfreym HMAsini oldindan hisoblash, bizdagi eng uzun shamlar oqimi — va GPUga har chaqiruvda tobora ko'proq uzunlik kombinatsiyalarini bering: B=1,2,4,,61B = 1, 2, 4, \dots, 61. Bu yerda CPU bazaviy chizig'i — ishlab chiqarishdagi halol dvigatel: barcha o'n ikki yadro bo'ylab prange bilan numba. Har bir paket uchun ikkalasini o'lchab, nisbatni olamiz.

Paket BB (kombinatsiya/chaqiruv) GPUning 12 yadroli CPU dvigateliga nisbatan tezlanishi
1 54.5x
2 102.5x
4 129.5x
8 187.4x
16 267.4x
32 245.0x
61 359.6x

Bu — real o'lchovlarda chizilgan S(B)=aB/(O+bB)S(B) = aB/(O + bB). B=1B = 1 da GPU allaqachon 54.5x oldinda — chunki bu taqqoslash sodda har-bar dvigateliga qarshi, ya'ni algoritmik yig'ilish bitta kombinatsiyada ham ichiga qo'shib qo'yilgan — lekin u o'z shiftidan hali juda uzoq: bir kombinatsiyali chaqiruvda qat'iy ustama hamon hukmron. Paketni ikki baravar oshiring — tezlanish deyarli ikki baravar oshib 102.5x bo'ladi; B=16B = 16 da u 267.4x; B=61B = 61 da 359.6x va ko'zga ko'rinib hali ham o'sishda davom etmoqda. Ustunlik masala hajmi bilan o'sadi. Bu GPUlar va parametr qidiruvlari haqidagi eng muhim yagona jumla va u GPU tezlanishlari odatda qanday keltirilishining — go'yo ular chipning o'zgarmas xossasi bo'lgandek — tamoman teskarisi.

Ikkita halollik eslatmasi — axir bu "Illyuziyalarsiz backtestlar" turkumi va silliq monoton jadval har doim shubhaga loyiq.

Birinchisi — pasayish: B=32B = 32 da 245.0x, ya'ni B=16B = 16 dagi 267.4x dan past. Bu gilam ostiga supurib yuboriladigan shovqin emas — bu chunk (bo'lak) chegarasi artefakti. Bizning conv1d 32 ta uzunlikni bitta kernel bo'lagiga joylaydi, shuning uchun B=32B = 32 roppa-rosa bitta bo'lakni bo'sh joysiz to'ldiradi, B=61B = 61 esa ikkinchi bo'lakka toshib o'tadi va bu tasodifan qurilmani yaxshiroq to'yintiradi. Roofline'ning maqsadi — trend, real qurilmada esa kvantlash zinalari bor; biz tebranishni chetlab o'tib qulay raqam terish o'rniga uni ochiq e'lon qilamiz.

Ikkinchisi, muhimrog'i: 54.5x ham, 359.6x ham sodda CPU dvigateliga nisbatan o'lchangan va ularning hech biri apparat yutug'i emas. Ikkala raqamning ichida hamon 27x algoritmik yig'ilish o'tiribdi. Agar CPU bazaviy chizig'ini CPUda ishlaydigan yig'ilgan algoritmga almashtirsangiz — o'sha formula, fp64, ikkala tomon ham optimallashtirilgan — har bir qator taxminan shu omilga qisqarar edi. Keyingi bo'lim aynan shu dekompozitsiyani aniq qilib beradi.

Halol dekompozitsiya: 27x algoritm karra 6.2x apparat

Bitta 167x ustun ikkita qavatlangan omilga bo'linmoqda — CPUga ham ochiq bo'lgan "algoritm" yorlig'li katta 27x va GPU haqiqatda qo'shadigan yagona qism bo'lgan "apparat" yorlig'li kichikroq 6.2x

Algoritmni kremniydan ajratish uchun bir xil ko'p taymfreymli to'rda ikkita emas, uchta yo'lni o'lchash kerak. Shuning uchun benchmark quyidagilarni yuritadi:

  1. cpu-engine — ishlab chiqarishdagi numba dvigateli, barcha yadrolarda har bir bar uchun tekislangan HMA. Sodda-lekin-parallel bazaviy chiziq.
  2. cpu-collapsed — yig'ilgan vazn vektorlari, np.correlate va gather, fp64, CPUda. (1) bilan bir xil apparat, yaxshiroq algoritm.
  3. gpu-mlx — yig'ilgan vaznlar Metal GPUda paketli conv1d sifatida, fp32. (2) bilan bir xil algoritm, boshqa apparat.

Ularni yonma-yon qo'ying — va to'liq ko'p taymfreymli sarlavha toza faktorlarga ajraladi:

167×gpu vs naive CPU  =  27×cpu-collapsed vs cpu-engine  ×  6.2×gpu vs cpu-collapsed\underbrace{167\times}_{\text{gpu vs naive CPU}} \;=\; \underbrace{27\times}_{\text{cpu-collapsed vs cpu-engine}} \;\times\; \underbrace{6.2\times}_{\text{gpu vs cpu-collapsed}}

Chap omil — 27x — algoritm: oldingi bo'limdagi har-bar-dan-konvolyutsiyaga yig'ilish. Uning GPUga hech qanday aloqasi yo'q. Uni numpy'da amalga oshiring — va noutbukingiz CPUsi bu ish yukida bitta refaktoring narxiga 27x tezlashadi. O'ng omil — 6.2x — apparat: Metal GPUning o'n ikki CPU yadrosidagi xuddi shu optimallashtirilgan algoritmdan halol, teng sharoitdagi yutug'i. Aynan shu 6.2x — GPU chindan zarur bo'lgan yagona qism.

Bu — maqolaning butun axloqiy xulosasi, arifmetika tilida aytilgani. Ishlab chiqaruvchi benchmarki, kutubxona README'si yoki hayajonlangan hamkasb sizga "GPUda 167x" ko'rsatganida, refleks bitta savol bo'lishi kerak: CPU bazaviy chizig'i nima edi? Agar bazaviy chiziq sodda realizatsiya bo'lsa — va u deyarli har doim shunday, chunki sekin bazaviy chiziq chiroyliroq slayd beradi — sarlavhaning katta qismi CPU ham haqli bo'lgan algoritmik yutuq bo'lib chiqadi, apparatga esa faqat qoldiq tegishli. Bu yerda qoldiq — 6.2x. 167x degan raqam apparatning hissasini taxminan 27 barobar bo'rttirib ko'rsatadi.

Va e'tibor bering, apparat omilining o'zi ham masala hajmi bilan siljidi. Kichik bitta taymfreymli qidiruvda GPUning eng yaxshi CPUdan haqiqiy yutug'i 3.2x edi. Kattaroq ko'p taymfreymli oldindan hisoblashda esa 6.2x — o'sha ikki chip, deyarli ikki baravar katta apparat ustunligi, faqatgina kattaroq ish yuki CPU ulgurolmay qolgunga qadar roofline bo'ylab GPUning tekis hisoblash shifti tomon balandroq ko'tarilgani uchun. Apparat ustunligi ham o'zgarmas emas. U o'sha ko'tarilib boruvchi egri chiziqdagi bir nuqta va bu egri chiziqda o'ngga siljish yo'li — paketni kattalashtirish va har bir kombinatsiyaga to'g'ri keladigan ishni boyitish.

Qaror qo'llanmasi: qidiruv qanchalik keng bo'lishi kerak?

Oddiy qaror oqimi: kichik qidiruv yoki har kombinatsiyaga yupqa ish CPUga yo'naltiriladi, minglab hisob-talab kombinatsiyali keng qidiruv GPUga yo'naltiriladi, GPU shoxida esa fp32 moslik tekshiruvi turibdi

Roofline'ni pul sarflashdan oldin qabul qilsa bo'ladigan qarorga qaytarib buklaymiz. GPU o'zini roofline'ning ikkala sharti bir vaqtda bajarilganda oqlaydi: qidiruvingiz paket tizmasidan o'ngda (BO/bB \gg O/b, ya'ni qat'iy ishga tushirish-va-uzatish ustamasi amortizatsiya qilingan) va har bir kombinatsiyaga to'g'ri keladigan ish hisob bilan chegaralangan (tekis shiftga yetadigan darajada boy arifmetik intensivlik, yupqa O(n) o'tish emas). O'lchaganlarimizdan kelib chiqib, aniq qilib aytganda:

  • Bitta taymfreymli strategiyaning bir necha o'nlab kombinatsiyasi: GPUni o'tkazib yuboring. Siz tizmadan chapdasiz; parallel numba'dan halol yutuq — allaqachon soniyaning o'ndan birini oladigan ishda ~3.2x. To'siq kernelda emas, uning atrofidagi hamma narsada.
  • Minglab kombinatsiyalar yoki chinakam ko'p taymfreymli / ko'p indikatorli oldindan hisoblash: GPU o'z o'rnini oqlaydi. Ustama amortizatsiya bo'ladi, umumiy konvolyutsiyalar arifmetik intensivlikni ko'taradi va apparat yutug'i 6.2x ga chiqib, paket bilan birga o'sishda davom etadi. Bu — GPU tuni bilan davom etadigan qidiruvni qahva tanaffusiga aylantiradigan rejim.
  • Avval CPU narvonidan ko'tariling — bu arzonroq va navbati oldinroq. CPUdagi 298x va 27x algoritmik yig'ilish tekin yoki deyarli tekin, va ular muqobil emas, oldshart: GPUning 6.2x i yig'ilgan algoritm ustiga keladi, uni esa baribir yozishingiz kerak edi. Sodda konveyerga (pipeline) mahkamlab qo'yilgan GPU asosan o'sha soddalikning o'zini o'lchaydi.

GPU shoxida tezlikka aloqasi yo'q soliq ham bor va uni narxga kiritishingiz shart: Apple'ning Metal GPUsida fp64 umuman yo'q. Hammasi fp32 da ishlaydi — nisbiy aniqlik ~1.2e-7. Bu tez harakatlanuvchi o'rtachalar uchun darslikdagi hiylani — O(n) prefiks-yig'indili WMAni — o'ldiradi: 30,000 atrofidagi narx masshtabida 150k bar davomida yig'ma yig'indilar ~1e14 ga yetadi, bu fp32 ning xavfsiz butun son diapazonidan yetti tartib narida; biz ~2e2 gacha nisbiy xatoliklarni o'lchadik (ikki yuz barobar, ikki foiz emas). Ishlaydigan yechim — to'g'ridan-to'g'ri oynali konvolyutsiya: unda har bir oyna yig'indisi o'zaro yaqin kattalikdagi cheklangan sondagi hadlardan yig'iladi va fp32 ~8e-7 gacha aniq qoladi. Shunda ham hma - hma3 ishorasiga qarab qaror qiladigan strategiya ikki egri chiziq deyarli tegib turgan chegaraviy barda kesishmani ora-sira teskariga ag'daradi, chunki fp32 yaxlitlashi deyarli-teng vaziyatni bir tomonga og'dirib yuboradi. Shuning uchun GPU yo'li u hech qachon bera olmaydigan bitma-bit bir xil natijani da'vo qilish o'rniga savdolar qanchaga farqlanganini o'lchaydigan ekvivalentlik tekshiruvi bilan birga keladi — PnL farqi bazis punktlarida, savdolar sonidagi nisbiy siljish. Bizning yurgizishda bu farq 479,016 ijrodan 90 tasining siljishi (0.019%) bo'ldi — ruxsat etilgan chegaradan ancha ichkarida, lekin yuk haqiqiy: GPUga o'tish shunchaki tezroq chastota emas, sonli moslik (parity) hisobotiga egalik qilish demakdir. Bu injenerlik xarajati ham o'zini oqlash hisobining bir qismi.

Raqamlar Apple'niki, egri chiziq esa hammaniki

Yuqoridagi har bir raqam — Apple M2 Max: GPU va CPU bitta umumiy xotirani bo'lishadigan yagona xotirali (unified memory) qurilma hamda ikkilangan aniqliksiz, faqat fp32 li GPU. Diskret NVIDIA yoki AMD kartasi konstantalarni o'zgartiradi va ularning har biri qaysi tomonga siljishini ochiq aytib qo'yish joiz, chunki raqamlar o'zgarsa-da, dalilning shakli saqlanib qoladi.

  • Uzatish ustamasi OO yomonlashadi, yaxshilanmaydi. Diskret karta PCIe ortida o'tiradi, shuning uchun kirishlar va natijalar yagona xotira chetlab o'tadigan shina orqali haqiqiy nusxa ko'chirishni boshdan kechiradi. Bu paket tizmasi O/bO/b ni o'ngga suradi — diskret GPU o'z ishga tushirilishini amortizatsiya qilishi uchun yanada kengroq qidiruv kerak bo'ladi. PCIe qurilmasida roofline'ning chap cheti yumshoqroq emas, tikroq.
  • Tekis shift a/ba/b balandroq bo'ladi. Ma'lumotlar markazi GPUsida integrallashganidan ancha ko'p FLOP/s va o'tkazuvchanlik bor, shuning uchun to'yintiruvchi qidiruvdagi asimptotik apparat yutug'i bizning 6.2x dan katta. Egri chiziqning o'ng tomoniga yetib borish mukofoti o'sadi; chap tomonda o'tirish uchun to'lov ham o'sadi.
  • fp64 qaytadi va u bilan birga prefiks-yig'indi hiylasi ham. Haqiqiy ikkilangan aniqlikka ega kartada O(n) prefiks-yig'indili WMA yana yaroqli va moslik tekshiruvini bitgacha aniqlik tomon qattiqlashtirish mumkin. Biz to'lagan o'ziga xos fp32 solig'i — prefiks-yig'indilar o'rniga to'g'ridan-to'g'ri konvolyutsiya, assert o'rniga farqni o'lchaydigan tekshiruv — Apple Silicon tafsiloti, qonun emas.

Bularning hech biri tezisni o'zgartirmaydi. Har qanday qurilmada S(B)=aB/(O+bB)S(B) = aB/(O + bB): amortizatsiya qilinishi shart bo'lgan qat'iy ustama va faqat o'ng tomondan yaqinlashiladigan asimptota. Konstantalar — apparat; egri chiziq — arifmetika. Birovning sarlavhasiga — shu jumladan biznikiga ham — ishonishdan oldin o'zingizning OO, aa va bb qiymatlaringizni besh qatorlik paket sinovi bilan o'lchang.

Bu qayerga ulanadi

Bu — backtest tezligi aslida qayerdan kelishi haqidagi kichik ich-turkumdagi to'rtinchi o'lchov va bo'laklar pul sarflashdan oldin nimani optimallashtirish kerak degan yagona dalilga birlashadi:

  • Tezlik narvoni faqat CPUning o'zida pandas'dan parallel numba'gacha 298x ga ko'tarildi va GPUni ochiq savol sifatida qoldirdi. Ushbu maqola unga javob beradi: GPU — real, lekin shartli beshinchi pog'ona bo'lib, eng yuqori CPU pog'onasidan 3.2x–6.2x ustun va faqat qidiruv roofline bo'ylab ko'tarilishga yetadigan darajada keng bo'lgandagina.
  • IPC solig'i xuddi shu yurishni teskari yo'nalishda qildi — jarayondan chiqish qancha turishini o'lchadi — va xuddi shu shakldagi xulosaga keldi: chegaraning o'zi (soket, GPU ishga tushirilishi) arzon; soliq — undan qanchalik tez-tez va qanchalik sergaplik bilan o'tishingizda. GPU chaqiruvlarini IPCni paketlagan sababingiz bilan bir xil sabab uchun paketlang: har kesishishning qat'iy narxini amortizatsiya qilish uchun.
  • Agregatlangan parquet keshi — GPU oldindan hisoblashi qiladigan ishning CPU tomonidagi versiyasi: umumiy indikatorlarni bir marta hisoblab, har bir kombinatsiyada qayta ishlatish. GPU shu qayta-ishlat-va-paketla tamoyilini shunchaki kremniy darajasiga olib chiqadi.
  • fp32 moslik tekshiruvi esa — miniatyuradagi backtest va jonli savdo mosligi muammosi: tez yo'lingiz etalondan ozgina farq qiladigan narsani hisoblagan zahoti siz farqning miqdoriy hisobotini qarzdorsiz, qo'l siltab qo'yish emas.

Bog'lovchi intizom — butun turkum ilgari suradigan o'sha intizom: sizga sotilayotgan narsaning aynan o'zini o'lchang. Tezlanish — bu nisbat, nisbatning esa surati va maxraji bor. GPUdan hafsala pir bo'lishlarning ko'pi xushomad uchun tanlangan maxrajdan — CPU bazaviy chizig'idan — keladi, GPU isrofining ko'pi esa roofline'ning chap chetidan chiqib keta olmaydigan darajada kichik qidiruvni yuritishdan.

Xulosalar

  1. GPU tezlanishi — raqam emas, egri chiziq. Bizning ko'p taymfreymli oldindan hisoblashimizda CPUdan ustunlik har chaqiruvda bitta kombinatsiyada 54.5x dan oltmish bittada 359.6x gacha bordi — o'sha chip, o'sha ma'lumotlar. Har qanday yakka raqam — shu egri chiziqdagi bir nuqta; u qanday paket hajmida o'lchanganini so'rang.
  2. CPU bazaviy chizig'ini har doim so'roqqa tuting. Ko'p taymfreymli sarlavhadagi 167x toza faktorlarga ajraladi: 27x algoritm (har-bar-dan-konvolyutsiyaga yig'ilish, u CPUni ham xuddi shunday tezlashtiradi) karra 6.2x haqiqiy apparat. Bu yerda GPUning eng yaxshi CPUdan adolatli yutug'i bitta taymfreymda 3.2x, ko'p taymfreymda 6.2x — 167x emas.
  3. Ustunlik masala hajmi bilan o'sadi va apparat omili ham shunday. Kattaroq paket va har kombinatsiyaga boyroq ish sizni roofline bo'ylab yuqoriga suradi: halol apparat yutug'ining o'zi shunchaki ish yukini kattalashtirish hisobiga 3.2x dan 6.2x ga ko'tarildi. Kichik qidiruvlar tizmadan chapda o'tiradi va deyarli foyda ko'rmaydi.
  4. Avval algoritmni tuzating va CPU narvonidan ko'tariling — GPU yutug'i ularning o'rniga emas, ustiga keladi. 6.2x baribir yozishingiz kerak bo'lgan yig'ilgan algoritmga nisbatan o'lchangan. GPUni sodda konveyerga mahkamlang — va o'lchaganingizning ko'pi kremniy emas, soddalik bo'ladi.
  5. GPUga o'tish — sonli moslik hisobotiga egalik qilish demak. Metal'da fp64 yo'q, prefiks-yig'indili WMA hiylasi narx masshtabida o'ladi (nisbiy xatolik ~2e2), kesishma ishorasiga qurilgan strategiyalar esa chegaraviy barlarda ag'darilib turadi. Farqni bazis punktlarida miqdoriy o'lchaydigan ekvivalentlik tekshiruvi bilan birga yetkazing; bu injenerlik xarajatini o'zini oqlash hisobingizga qo'shing.

Kimdir sizga GPU uning backtestini yuz barobar tezlashtirganini aytsa, u sizga deyarli hech narsa aytmadi. Undan paket hajmi va CPU bazaviy chizig'ini so'rang — shunda o'sha yuz odatda tekinga olsa bo'ladigan algoritmik yutuqqa o'ralgan bir xonali apparat yutug'iga aylanadi. Yetarlicha keng qidiruvda bunga ega bo'lish arziydi — aynan roofline aytgan sabablarga ko'ra va birorta ham ortiqcha sababsiz.

blog.disclaimer

Authors

Eugen Soloviov
Eugen Soloviov

Trading-systems engineer

Trading-systems engineer building bots since 2017: cross-exchange arbitrage (connected up to 30 venues), cointegration-based pairs arbitrage across spot and futures, scalping, news and sentiment-driven strategies, trend algorithms, and portfolio management and balancing algorithms. Also builds sub-millisecond order execution, big-data warehouses, backtesting engines, AI agents, and trading interfaces (incl. open-source profitmaker.cc). Stack: JS/TS, Python, Rust/Zig/Go, DevOps, backend, frontend, architecture.

Newsletter

Bozordan bir qadam oldinda bo'ling

Sun'iy intellekt savdo tahlillari, bozor tahlili va platforma yangiliklari uchun bizning xabarnomaga obuna bo'ling.

Biz sizning maxfiyligingizni hurmat qilamiz. Istalgan vaqtda obunadan chiqishingiz mumkin.