📝

Draft article

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

← Макалаларга кайтуу
July 7, 2026
5 мүн окуу

GPU качан өзүн актайт: параметр сыдыруунун roofline модели, же жарнамалык 167x чындыгында — 27x алгоритм менен 6.2x жабдыктын көбөйтүндүсү

GPU качан өзүн актайт: параметр сыдыруунун roofline модели, же жарнамалык 167x чындыгында — 27x алгоритм менен 6.2x жабдыктын көбөйтүндүсү
#algotrading
#backtest
#өндүрүмдүүлүк
#gpu
#roofline
#оптималдаштыруу
Part 9 of 10 · Collection
High-Performance Backtest Engines

"Иллюзиясыз бэктесттер" сериясындагы макала.

Ылдамдык шатысы атайылап канааттандырбаган нота менен аяктаган. Биз 80 комбинациялуу параметр сыдырууну (parameter sweep) ноутбуктун CPU-сунда pandas-тын 69.9 секундасынан параллель numba-нын 0.23 секундасына түшүргөнбүз — өлчөнгөн 298x — андан соң GPU жетишпеген тепкич эмес деп ырастаганбыз. Комментарийлер бөлүмү муну унчукпай кабыл алган жок — жана туура кылды. "Жетишпеген тепкич эмес" — бул бир жүктөм, бир өлчөм жөнүндөгү ырастоо. Ал жаратылыш мыйзамы эмес. Ошондуктан бул макала адилет ишти жасайт да, GPU-ну сыноо стендине коет.

Натыйжа — өкүм эмес, ийри сызык. GPU-нун CPU-дан озуусу слайдга басып чыгара турган жалгыз сан эмес; ал ар бир чакырыкта ага канча жумуш бергениңдин функциясы. Биздин көп таймфреймдүү индикаторлорду алдын ала эсептөөдө GPU-нун CPU движогунан ылдамдануусу бир чакырыкта бир параметр комбинациясын сураганда 54.5x болсо, бир заматта 61 комбинацияны сураганда 359.6x-ке жетет. Ошол эле ядро, ошол эле маалымат, ошол эле жабдык — өзгөргөн жалгыз нерсе — топтом (batch). Ошол сандардын бирин билдирип, экинчисин жашырган бенчмарк GPU-ну өлчөп жаткан жери жок — ал жарнамалык сан тандап жатат.

Атүгүл 359.6x да көрүнгөнүндөй эмес. Кабыгын аарчысаң, көп таймфреймдүү чоң жарнамалык 167x — 27x алгоритмдин (CPU-ну да 27x ылдамдаткан кайра жазуунун) жана 6.2x чыныгы жабдыктын көбөйтүндүсүнө ажырайт. 27x-ти GPU жасаган жок. Аны математика жасады. Бул макала — ошол экөөнү айырмалоо жөнүндө, анткени аларды чаташтыруу аркылуу git commit бекер эле чечмек болгон маселеге $2,000 турган видеокарта сатылат.

Булагы: төмөндөгү бардык сандар Apple M2 Max үстүндө өлчөнгөн — MLX аркылуу Metal GPU-да fp32 менен он эки CPU агымындагы fp64 numba салыштырылган — биздин engine_multitf_gpu.py жана bench_param_sweep.py бенчмарк скрипттеринен алынган, жана ар бири GPU менен CPU жолдору бирдей бүтүмдөрдү берерин ырастаган эквиваленттүүлүк текшерүүсүнөн өткөн. Бул макалага коштомо ачык илимий эмгек жок — жазуу катары скрипттердин өзү кызмат кылат.

Суроо — бенчмарк эмес, roofline

Roofline графиги: оң жагында түз эсептөө шыбы, сол жагында эс тутумдун өткөрүү жөндөмдүүлүгүнүн тик жантаймасы, жана үстөк чыгым үстөмдүк кылган бурчтан кыр чекитин көздөй жантайма боюнча өйдөлөп бараткан топтом чекити

"GPU канчага ылдамыраак" деген суроонун жалгыз жообу жок болушунун себеби — roofline модели (Williams, Waterman & Patterson, 2009). Процессордун жетүүгө мүмкүн болгон өндүрүмдүүлүгү бир учурда эки шып менен чектелген: бири — эсептөөнүн чокусу (FLOP/s) аныктаган түз шып, экинчиси — эс тутумдун өткөрүү жөндөмдүүлүгүн арифметикалык интенсивдүүлүккө — ташыган ар бир байтка жасаган пайдалуу операциялардын санына — көбөйткөн жантайган шып. Байтына арзан жумуш жантайган шыптын астында жашайт жана өткөрүү жөндөмдүүлүгүнө байланган (bandwidth-bound); байтына бай жумуш түз шыпка жетет жана эсептөөгө байланган (compute-bound). GPU-нун түз шыбы CPU-нукунан асман тирей бийик турат, бирок анын жантайган шыбы жана — эң башкысы — ар бир чакырыктын туруктуу баасы ылдый жакка ошончолук жеңил масштабталбайт.

Параметр сыдыруу үчүн графиктин сол жагында үчүнчү мүчө үстөмдүк кылат: ишке киргизүү жана ташуу үстөк чыгымы (overhead). Ар бир GPU чакырыгы болжол менен туруктуу баа төлөйт — ядрону жөнөтүү, кирүү маалыматтарын эс тутум чек арасы аркылуу (Apple Silicon-до бириктирилген, бирок бекер эмес) ташуу, натыйжаларды кайра алып келүү. BB комбинациядан турган топтомдун аткарылуу убактысын мындай моделдейбиз

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

мында OO — ошол туруктуу үстөк чыгым, bb — GPU-нун бир комбинацияга кеткен чектик баасы, ал эми aa — CPU-нуку. Анда ылдамдануу

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

Ушул жалгыз бөлчөк бүт макаланы түшүндүрөт. Кичине BB-де бөлүмүндөгү OO катышты эзип салат — сен GPU-ну ойготконуң үчүн төлөдүң, бирок аны дээрлик колдонгон жоксуң. BB өскөн сайын OO көбүрөөк комбинацияга жайылып амортизацияланат да, ылдамдануу өзүнүн асимптотасы a/ba/b-ни — чыныгы жабдык катышын — көздөй өйдөлөйт. Жарым жолдогу чекит B=O/bB = O/b жерде турат: бул — топтом мейкиндигиндеги "кыр чекити", ал GPU өз мүмкүнчүлүгүнүн жок дегенде жарымына жетиши үчүн сыдырууң канчалык кенен болушу керектигин айтып берет. Бир нече ондогон комбинациялуу сыдыруу ал кырдан алыс солдо турат. Миңдеген комбинациялуу сыдыруу GPU акыры өз шыбын актаган түз бөлүктө турат.

Демек туура суроо эч качан "GPU ылдамыраакпы" эмес. Туура суроо: "менин сыдыруум кырдын оң жагындабы, жана ал жакка жеткенде ар бир комбинацияга кеткен жумушум түз шыпка жете тургандай эсептөөгө байланганбы." Экөө тең аткарылышы керек. Макаланын калган бөлүгү ошол босоголор иш жүзүндө кайда экенин өлчөйт.

Бир таймфреймдин өкүмү: GPU араң утат

Ошол эле 80 комбинациялуу бир таймфреймдүү сыдыруу үчүн эки мамыча: секундасына 246 комбинациялык он эки өзөктүү CPU пулу менен катарында 779 комбинациялык GPU — туңгуюк эмес, жупуну 3.2x айырма

Ылдамдык шатысы колдонгон жүктөмдөн баштайлы: бир таймфреймдүү HMA/HMA3 сыдыруусу, 150,000 бар боюнча 80 комбинация. Ал шатыга биз алтынчы тепкичти коштук — M5, индикаторлор MLX аркылуу Apple GPU-да, бүтүмдөр мурдагыдай эле CPU-да чыгарылат. Жылытылып, үч жүгүртүүнүн эң жакшысы алынып, эквиваленттүүлүк дарбазасы жашыл күйүп турат:

Ыкма Убакыт pandas-ка каршы Комбинация/сек
M0 pandas + цикл 287.08s 1.0x 0.3
M2 numba (1 өзөк) 2.02s 142x 39.7
M4 mp + numba (12 өзөк) 0.33s 883x 245.9
M5 MLX GPU (fp32) 0.10s 2796x 779.2

Аңкоо удаалаш базага салыштырганда GPU баатыр көрүнөт — 2,796x. Бирок бул ак ниет адам жасабай турган салыштыруу: ал жакшы GPU реализациясын эң начар CPU реализациясына каршы коет. GPU-ну иш жүзүндө колдоно турган CPU менен катар кой — ошол эле ядро бардык он эки өзөктө, M4 — жана утуш токтоо 3.2x-ке чейин кыйрайт (секундасына 779 менен 246 комбинация). Бүтүндөй бир видеокарта, бүт сыдырууну жалгыз аткарып, он эки өзөктүү CPU пулун болгону үч эсеге утат.

Үч бүтүн эки — жокко эсе эмес. Бирок ал GPU сатып алуунун себеби да эмес. Жана бул так ушундай тар сыдыруу үчүн roofline алдын ала айткан нерсе: 80 комбинация — кырдан солдо. Туруктуу ишке киргизүү-ташуу үстөк чыгымы OO 0.10 секунддук жумуштун дагы деле олуттуу үлүшү, ошондуктан a/ba/b асимптотасына биз эч жетпейбиз. Андан да жаманы, комбинацияга кеткен баанын бир бөлүгү — O(n) бүтүм чыгаруу өтмөгү, аны биз атайылап CPU-да калтырдык — бул GPU таптакыр ылдамдата албай турган мүчө (эмне үчүн экени — кийинки бөлүмдө). Ушул өлчөмдөгү бир таймфреймдүү изилдөө цикли үчүн ылдамдык шатысынын баштапкы өкүмү күчүндө калат: GPU — жетишпеген тепкич эмес. Параллель numba сени ансыз да 0.23–0.33 секундага жеткирген, аны 0.10 секундага чейин кыруу изилдөөчүнүн жолун ачпайт. Аны сыдыруунун тегерегиндеги оркестрлөө ачат.

Бул өкүмдөгү кызыктуу сөз — ушул өлчөмдөгү. Топтом огу боюнча оңго жыл — окуя башкача өнүгөт.

Чыгым чындыгында кайда жашайт

Топтомду чоңойтуудан мурун эмне үчүн акча төлөп жатканыбызды карап алалы, анткени roofline кымбат бөлүгүң эсептөөгө байланган учурда гана сыйлайт. Сыдыруунун профилин алсаң, анын дээрлик баары — бир эле нерсе: салмактанган жылма орточолордун конволюциялары (convolution). Бир HMA — үч WMA; бир HMA3 — төртөө; ар бир комбинация аларды бүткүл катар боюнча кайрадан жүгүртөт. Бүтүм чыгаруу — эки индикатор массивин аралап өтүп, hma - hma3 белгисинин алмашууларын таап, аткарууларды каттоо — бир гана арзан O(n) өтмөк. Бул сыдыруу — трейдинг стратегиясынын костюмун кийген конволюциялык жүктөм.

Бул бөлүнүш — так roofline-дын эки режими:

  • Конволюциялар эсептөөгө байланган. Ар бир баа көптөгөн кайчылаш терезе суммаларына окулат, ошондуктан арифметикалык интенсивдүүлүк — ташылган байтка операциялардын саны — жогору. Бул жумуш түз эсептөө шыбына умтулат, ал эми асман тиреген шып — дал GPU-нуку. Андан да жакшысы, терезелер комбинациялардын ортосунда да кайчылашат: узундугу 40 болгон WMA ондогон комбинацияга керек, ошондуктан топтомдук алдын ала эсептөө аны комбинация сайын кайра эсептебей, бир жолу эсептеп бөлүшөт. Топтомдоо ишке киргизүү чыгымын амортизациялап эле койбойт; ал окууларды кайра колдонуу аркылуу арифметикалык интенсивдүүлүктү да көтөрөт. GPU-га таандык бөлүк — ушул.
  • Бүтүм чыгаруу өткөрүү жөндөмдүүлүгүнө байланган жана бутактуу. Бир удаалаш өтмөк, ар бир кесилиште маалыматка көз каранды бутактар, кайра колдонуу дээрлик жок. Анын арифметикалык интенсивдүүлүгү полдун түбүндө, ал эми башкаруу агымы SIMD түзүлүшүнө кас. Аны GPU-га түртүү аз пайда берип, көп чыгым алмак; ал CPU-да калат. Демек ал — Амдал мыйзамы боюнча бөлүнүштүн удаалаш куйругу: GPU ылдамдануусу эч качан тешип өтө албай турган туруктуу пол, жана бир таймфреймдүү сан 3.2x-те токтоп калышынын бир себеби.

Бул ядронун көп таймфреймдүү вариантында экинчи, курчураак сабак жашырылган, жана ал — биз түшүндүрөбүз деп убада кылып келе жаткан 27x-тин булагы. Көп таймфреймдүү движок жогорку таймфреймдин HMA-сын базалык 1 мүнөттүк индекске келечекке шыкаалабай (look-ahead жок) тегиздейт. Муну маңдайдагы жол менен жазсаң, ар бир барга O(length^1.5) жумуш чыгат — жогорку таймфреймдин жылма орточолорун ар бир базалык барда кайра эсептөө. Бирок тегизделген HMA акыркы бир нече жабылган жогорку таймфреймдик шамдын кыска буферине жана учурдагы жабылуу баасына карата сызыктуу, ошондуктан ар бир барга жасалчу бүт эсеп туруктуу салмак векторуна кыскарат: жабылган шамдардын катары боюнча бир conv1d, артынан O(n) gather. Жүздөгөн миллион ашыкча операция бир топ кыска катар боюнча жасалган бир конволюцияга айланат.

Бул кыскаруу — жабдыктын эмес, алгоритмдин утушу. Бул жакшыраак формула. Ал GPU-да иштейт, жана CPU-да да так ошондой жакшы иштейт — np.correlate жана gather, fp64 менен. Муну бек эсиңде тут: көп таймфреймдүү жарнамалык сандын эң чоң фактору — GPU-су таптакыр жок машинага да жеткиликтүү кайра жазуу. Акырында 167x-ти ажыратканыбызда, бул — ошол 27x.

Озуу топтомдун өлчөмү менен өсөт

GPU менен CPU ортосундагы ылдамдануунун топтом өлчөмүнө карата өсүп бараткан ийриси: бир комбинацияда 54.5x-тен алтымыш бирде 359.6x-тен ашканга чейин, отуз экидеги жалгыз чөгүү чанк чегиндеги артефакт деп белгиленген

Эми roofline бизге буйруган өлчөөгө келели. Кымбат окту алалы — 1 мүнөттүк базалык катардагы, башкача айтканда колубуздагы эң узун шам агымындагы тегизделген жогорку таймфреймдик HMA-нын алдын ала эсептелиши — жана GPU-га ар бир чакырыкта барган сайын көбүрөөк узундук комбинациясын берели: B=1,2,4,,61B = 1, 2, 4, \dots, 61. Бул жердеги CPU базасы — чынчыл продакшн движок: бардык он эки өзөктө prange менен иштеген numba. Ар бир топтом үчүн экөөнү тең өлчөп, катышын алабыз.

Топтом BB (комбинация/чакырык) 12 өзөктүү CPU движогуна каршы GPU ылдамдануусу
1 54.5x
2 102.5x
4 129.5x
8 187.4x
16 267.4x
32 245.0x
61 359.6x

Бул — чыныгы өлчөөлөр менен тартылган S(B)=aB/(O+bB)S(B) = aB/(O + bB). B=1B = 1 учурунда GPU мурунтан эле 54.5x алдыда — анткени бул салыштыруу аңкоо ар-бир-барлык движокко каршы, ошондуктан алгоритмдик кыскаруу бир комбинацияда да ичине бүктөлгөн — бирок ал өз шыбынан алда канча алыс: бир комбинациялык чакырыкта туруктуу үстөк чыгым дагы деле үстөмдүк кылат. Топтомду эки эсе көбөйт — ылдамдануу дээрлик эки эселенип 102.5x болот; B=16B = 16 болгондо ал 267.4x; B=61B = 61 болгондо 359.6x жана көрүнөө дагы эле өсүүдө. Озуу маселенин өлчөмү менен өсөт. Бул — GPU менен параметр сыдыруулар тууралуу эң маанилүү жалгыз сүйлөм, жана ал GPU ылдамдануулары адатта кандай тартипте айтыларына — чиптин туруктуу касиети сыңары — түптамырынан карама-каршы.

Эки чынчылдык эскертүү, анткени бул — Иллюзиясыз бэктесттер сериясы, ал эми таптаза монотондуу таблица ар дайым шектенүүгө татыктуу.

Биринчиси — чөгүү: B=32B = 32 245.0x көрсөтөт, бул B=16B = 16 учурундагы 267.4x-тен төмөн. Бул килем алдына шыпырып сала турган ызы-чуу эмес — бул чанк чегиндеги артефакт. Биздин conv1d 32 узундукту бир ядро чанкына жыйнайт: B=32B = 32 так бир чанкты боштуксуз толтурат, ал эми B=61B = 61 экинчи чанкка ташып, түзүлүштү жакшыраак каныктырып калат. Roofline-дын маңызы — тенденцияда, ал эми чыныгы түзүлүштүн ичинде кванттоо тепкичтери бар; биз ыңгайлуу жерин гана терип отурбай, солкулдаган жерин да кабарлайбыз.

Экинчиси — жана андан да маанилүүсү: 54.5x да, 359.6x да аңкоо CPU движогуна каршы алынган, жана экөөнүн бири да жабдык утушу эмес. Эки санда тең 27x алгоритмдик кыскаруу дагы деле камтылган. Эгер CPU базасын CPU-да иштеген кыскарган алгоритмге алмаштырсаң — ошол эле формула, fp64, эки тарап тең оптималдаштырылган — таблицанын ар бир сабы болжол менен ошол факторго кичирейт эле. Кийинки бөлүм так ушул ажыратууну аткарат.

Чынчыл ажыратуу: 27x алгоритм менен 6.2x жабдыктын көбөйтүндүсү

Жалгыз 167x мамычасы эки катталган факторго бөлүнөт — CPU-га да жеткиликтүү, алгоритм деп белгиленген чоң 27x жана GPU чындап кошкон жалгыз бөлүк болгон, жабдык деп белгиленген кичирээк 6.2x

Алгоритмди кремнийден бөлүп алуу үчүн ошол эле көп таймфреймдүү тордо эки эмес, үч жолду өлчөө керек. Ошондуктан бенчмарк үчөөнү жүгүртөт:

  1. cpu-engine — продакшн numba движогу, бардык өзөктөрдө ар бир барга тегизделүүчү HMA. Аңкоо-бирок-параллель база.
  2. cpu-collapsed — кыскарган салмак векторлору, np.correlate жана gather, fp64, CPU-да. (1) менен бирдей жабдык, бирок жакшыраак алгоритм.
  3. gpu-mlx — кыскарган салмактар Metal GPU-да топтомдук conv1d түрүндө, fp32. (2) менен бирдей алгоритм, бирок башка жабдык.

Үчөөнү катар тизсең, көп таймфреймдүү жарнамалык сан толугу менен таза ажырайт:

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}}

Сол фактор, 27x — алгоритм: мурунку бөлүмдө айтылган ар-бир-бардан-конволюцияга кыскаруу. Анын GPU-га эч кандай тиешеси жок. Аны numpy менен ишке ашырсаң, ноутбугуңдун CPU-су бул жүктөмдө бир рефакторингдин баасына 27x ылдамдайт. Оң фактор, 6.2x — жабдык: ошол эле оптималдаштырылган алгоритмге каршы он эки CPU өзөгүнүн үстүнөн Metal GPU-нун чынчыл, тең шарттагы утушу. Ошол 6.2x — GPU чындап керек болгон жалгыз үлүш.

Бул — макаланын бүт моралы арифметика тилинде айтылганы. Сатуучунун бенчмаркы, китепкананын README-си же шыктанган кесиптешиң сага "GPU-да 167x" көрсөткөндө, рефлекс бир гана суроо болушу керек: CPU базасы кайсы болгон? Эгер база аңкоо реализация болсо — ал эми дээрлик дайыма ошондой, анткени жай база слайдды кооздойт — анда жарнамалык сандын көбү CPU-га да тиешелүү болгон алгоритмдик утуш, ал эми жабдыкка калганы — калдык гана. Бул жерде калдык — 6.2x. 167x деген цитата жабдыктын салымын болжол менен 27 эсе апыртат.

Жана жабдык факторунун өзү да маселенин өлчөмү менен жылганына көңүл бур. Кичине бир таймфреймдүү сыдырууда GPU менен эң мыкты CPU ортосундагы чыныгы утуш 3.2x болчу. Чоңураак көп таймфреймдүү алдын ала эсептөөдө — 6.2x: ошол эле эки чип, жабдык артыкчылыгы дээрлик эки эсе, жалгыз себеби — чоңураак жүктөм CPU үлгүрө электе roofline боюнча GPU-нун түз эсептөө шыбын көздөй тереңирээк түртөт. Жабдык озуусу да туруктуу эмес. Ал да ошол эле өсүп жаткан ийринин бир чекити, ал эми ийри боюнча оңго жылуунун жолу — топтомду чоңойтуу жана ар бир комбинациянын жумушун байытуу.

Чечим колдонмосу: сыдыруу канчалык кенен болушу керек?

Жөнөкөй чечим агымы: кичине сыдыруу же комбинациясына жука жумуш CPU-га багытталат, миңдеген эсептөөгө оор комбинациялуу кенен сыдыруу GPU-га багытталат, ал эми GPU бутагында fp32 паритет дарбазасы турат

Roofline-ды акча коротуудан мурун кабыл алчу чечимге кайра бүктөйлү. GPU roofline-дын эки шарты бир учурда аткарылганда өзүн актайт: сыдырууң топтом кырынын оң жагында (BO/bB \gg O/b, башкача айтканда туруктуу ишке киргизүү-ташуу чыгымы амортизацияланган) жана ар бир комбинациянын жумушу эсептөөгө байланган (жука O(n) өтмөк эмес, түз шыпка жеткидей арифметикалык интенсивдүүлүгү бай). Так айтканда, өлчөгөнүбүздөн улам:

  • Бир таймфреймдүү стратегиянын бир нече ондогон комбинациясы: GPU-ну өткөрүп жибер. Сен кырдан солдосуң; параллель numba-га салыштырмалуу чынчыл утуш — ансыз да секунданын ондон бир бөлүгүн алган жумушта ~3.2x. Тар жер — ядродо эмес, анын тегерегиндеги бардык нерседе.
  • Миңдеген комбинация, же чыныгы көп таймфреймдүү / көп индикатордук алдын ала эсептөө: GPU өз ордун актайт. Үстөк чыгым амортизацияланат, бөлүшүлгөн конволюциялар арифметикалык интенсивдүүлүктү көтөрөт, ал эми жабдык утушу 6.2x-ке чейин көтөрүлүп, топтом менен кошо өсө берет. Бул — GPU түн бою созулчу сыдырууну кофе тыныгуусуна айланткан режим.
  • Адегенде CPU шатысына чык — ал арзаныраак жана биринчи келет. CPU-дагы 298x жана 27x алгоритмдик кыскаруу бекер же бекерге жакын, жана алар альтернатива эмес, милдеттүү өбөлгө: GPU-нун 6.2x-и кыскарган алгоритмдин үстүнө келет, ал эми ал алгоритмди сен баары бир жазышың керек болчу. Аңкоо пайплайнга бурап коюлган GPU негизинен аңкоолуктун өзүн өлчөйт.

GPU бутагында ылдамдыкка эч тиешеси жок дагы бир салык бар, жана аны баага кошуп эсептөө милдет: Apple-дин Metal GPU-сунда fp64 таптакыр жок. Баары fp32 менен иштейт, салыштырмалуу тактыгы ~1.2e-7. Бул ыкчам жылма орточолордун окуу китебиндеги амалын — O(n) префикстик суммалуу WMA-ны — өлтүрөт: баа масштабы 30,000 тегерегинде болгондо 150k бар боюнча топтолгон суммалар ~1e14 деңгээлине жетет — бул fp32-нин коопсуз бүтүн сан диапазонунан жети даражага ашык; биз өлчөгөн салыштырмалуу каталар ~2e2 деңгээлине чейин жетти (эки жүз эсе, эки пайыз эмес). Иштей турган формулировка — түз терезелүү конволюция: анда ар бир терезенин суммасы өлчөмү салыштырма мүчөлөрдүн чектелген санынан турат, жана fp32 тактыгы ~8e-7 деңгээлинде сакталат. Ошондо да hma - hma3 белгиси боюнча чечкен стратегия эки ийри дээрлик тийишип турган чектеги барда кесилишти анда-санда которуп жиберет, анткени fp32 тегеректөөсү дээрлик тең абалды бир жакка оодарып коет. Ошондуктан GPU жолу эч качан камсыз кыла албай турган бит-биттик бирдей чыгарылышты талап кылуунун ордуна бүтүмдөр канчалык ажырап кеткенин өлчөгөн эквиваленттүүлүк дарбазасы менен жеткирилет — PnL айырмасы базистик пункттарда, бүтүм санынын салыштырмалуу жылышы. Биздин жүгүртүүдө ал ажырым 479,016 аткаруунун ичинен 90 жылган аткаруу (0.019%) болду — чектөөнүн ичине эркин батат, бирок жүк чыныгы: GPU-га өтүү — жөн гана тезирээк такт эмес, сандык паритеттин жообун өз мойнуңа алуу дегени. Бул инженердик чыгым да өзүн актоо эсебинин бир бөлүгү.

Сандар Apple түспөлдүү; ийри — андай эмес

Жогорудагы ар бир цифра — Apple M2 Max: GPU менен CPU бир бассейнди бөлүшкөн бириктирилген эс тутумдуу түзүлүш жана кош тактыгы жок, fp32 менен гана иштеген GPU. Дискреттик NVIDIA же AMD картасы константаларды өзгөртөт, жана алардын ар бири кайсы тарапка жыларын ачык айтып кетүү зарыл, анткени сандар аман калбаса да, аргументтин формасы аман калат.

  • Ташуу үстөк чыгымы OO жакшырбайт — начарлайт. Дискреттик карта PCIe артында отурат, ошондуктан кирүү маалыматтары менен натыйжалар шина аркылуу чыныгы көчүрмө жасайт — бириктирилген эс тутум мындан кутулган. Бул топтом кырын O/bO/b оңго түртөт: дискреттик GPU өз ишке киргизүүсүн амортизациялашы үчүн ого бетер кенен сыдыруу керек. PCIe түзүлүшүндө roofline-дын сол чети жумшагыраак эмес, тигирээк.
  • Түз шып a/ba/b бийигирээк болот. Дата-борбордук GPU-нун FLOP/s-у да, өткөрүү жөндөмдүүлүгү да интеграцияланганга караганда алда канча көп, ошондуктан каныккан сыдыруудагы асимптотикалык жабдык утушу биздин 6.2x-тен чоң. Ийринин оң жагына жеткендин сыйлыгы өсөт; сол жагында отургандын төлөмү да өсөт.
  • fp64 кайтып келет, аны менен кошо префикстик сумма амалы да. Чыныгы кош тактыктуу картада O(n) префикстик суммалуу WMA кайра жарактуу, ал эми паритет дарбазасын бит-бирдейликти көздөй катаалдаштырса болот. Биз төлөгөн конкреттүү fp32 салыгы — префикстик суммалардын ордуна түз конволюция, assert-тин ордуна ажырымды өлчөгөн дарбаза — Apple Silicon-дун өзгөчөлүгү, мыйзам эмес.

Мунун бири да тезисти өзгөртпөйт. Каалаган түзүлүштө S(B)=aB/(O+bB)S(B) = aB/(O + bB): амортизациялоого милдеттүү туруктуу үстөк чыгым, оң тараптан гана жакындай турган асимптота. Константалар — жабдык; ийри — арифметика. Кимдир бирөөнүн жарнамалык санына — биздикин кошо — ишенгенден мурун өзүңдүн OO, aa жана bb константаларыңды беш саптык топтом сыдыруусу менен өлчөп ал.

Бул эмне менен байланышат

Бул — бэктест ылдамдыгы чындыгында кайдан келери тууралуу чакан ички сериянын төртүнчү өлчөөсү, жана анын бөлүктөрү акча коротуудан мурун эмнени оптималдаштыруу керек деген бирдиктүү аргументке биригет:

  • Ылдамдык шатысы pandas-тан параллель numba-га чейин чыгып, жалгыз CPU-да эле 298x алган, ал эми GPU-ну ачык суроо бойдон калтырган. Бул макала ага жооп берет: GPU — чыныгы, бирок шарттуу бешинчи тепкич, эң жогорку CPU тепкичинен 3.2x–6.2x артык, жана сыдыруу roofline боюнча өйдөлөгүдөй кенен болгондо гана.
  • IPC салыгы ошол эле жүрүштү тескери багытта жасаган — процесстин сыртына чыгуу канча турарын өлчөгөн — жана ошол эле формадагы тыянакка келген: чек аранын өзү (сокет, GPU ишке киргизүү) арзан; салык — аны канчалык көп жана канчалык майда сүйлөшүп кесип өткөнүңдө. GPU чакырыктарыңды IPC-ни топтогон эле себеп менен топто: ар бир кесип өтүүнүн туруктуу баасын амортизациялоо үчүн.
  • Агрегацияланган parquet кэши — GPU алдын ала эсептөөсүнүн CPU жактагы версиясы: жалпы индикаторлорду бир жолу эсептеп, аларды ар бир комбинацияда кайра колдонуу. GPU болсо ошол кайра колдонуп-топтоо принцибин кремнийдин өзүнө жеткирет.
  • Ал эми fp32 паритет дарбазасы — миниатюрадагы бэктест менен жандуу сооданын паритети маселеси: ыкчам жолуң эталонуңдан бир аз башка нерсени эсептеген заматта сен ажырым тууралуу кол шилтемени эмес, сан менен өлчөнгөн отчетту карыз болосуң.

Байланыштырган тартип — ушул серия бүтүндөй түртүп келе жаткан ошол эле тартип: сага сатып жаткан нерсени өзүң өлчө. Ылдамдануу — катыш, ал эми катыштын алымы жана бөлүмү бар. GPU-дан көңүл калуунун көбү бөлүмдөн — кооз көрүнүш үчүн тандалган CPU базасынан — келет, ал эми GPU ысырабы көбүнчө roofline-дын сол четинен чыга албай турганчалык кичине сыдыруу жүгүртүүдөн келет.

Тыянактар

  1. GPU ылдамдануусу — сан эмес, ийри. Биздин көп таймфреймдүү алдын ала эсептөөдө CPU-дан озуу чакырыгына бир комбинацияда 54.5x-тен алтымыш бирде 359.6x-ке чейин созулду — ошол эле чип, ошол эле маалымат. Ар кандай жалгыз цифра — ошол ийринин бир чекити; кайсы топтом өлчөмүндө өлчөнгөнүн сура.
  2. CPU базасын ар дайым сурак кыл. Көп таймфреймдүү жарнамалык 167x таза түрдө 27x алгоритмге (ар-бир-бардан-конволюцияга кыскаруу, ал CPU-ну да так ошончолук ылдамдатат) жана 6.2x чыныгы жабдыкка ажырайт. Бул жерде GPU менен эң мыкты CPU-нун адилет салыштыруусу — бир таймфреймде 3.2x, көптө 6.2x — 167x эмес.
  3. Озуу маселенин өлчөмү менен өсөт, жабдык фактору да ошондой. Чоңураак топтом жана ар бир комбинациянын байыраак жумушу сени roofline боюнча өйдө түртөт: чынчыл жабдык утушунун өзү жүктөмдү чоңойткон эле себептен 3.2x-тен 6.2x-ке көтөрүлдү. Кичине сыдыруулар кырдан солдо отурат жана пайданы араң көрөт.
  4. Адегенде алгоритмди оңдоп, CPU шатысына чык — GPU утушу алардын ордуна эмес, үстүнө келет. 6.2x кантсе да жазышың керек болгон кыскарган алгоритмге каршы өлчөнгөн. GPU-ну аңкоо пайплайнга бурап кой — өлчөгөнүңдүн көбү кремний эмес, аңкоолук болот.
  5. GPU-га өтүү — сандык паритеттин жообун өз мойнуңа алуу. Metal-да fp64 жок, префикстик суммалуу WMA амалы баа масштабында өлөт (салыштырмалуу ката ~2e2), ал эми кесилиштин белгисине таянган стратегиялар чектеги барларда которулуп кетет. Ажырымды базистик пункт менен санга айландырган эквиваленттүүлүк дарбазасын кошо жеткир; ал инженердик чыгымды өзүн актоо эсебиңе кошуп сана.

Кимдир бирөө сага GPU анын бэктестин жүз эсе ылдамдатты десе, ал дээрлик эч нерсе айткан жок. Андан топтомдун өлчөмүн жана CPU базасын сура — ошондо ал жүз, адатта, бекер эле алса болмок алгоритмдик утушту ороп турган бир орундуу жабдык утушуна айланат; жетишерлик чоң сыдырууда ага ээ болгонго татыйт — так roofline айткан себептер үчүн, жана бир да ашыкча себеп үчүн эмес.

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

Рынктан бир кадам алдыда болуңуз

AI соода аналитикасы, рынок талдоолору жана платформа жаңылыктары үчүн биздин жаңылыктар бюллетенине жазылыңыз.

Биз сиздин купуялыгыңызды урматтайбыз. Каалаган убакта жазылымдан чыга аласыз.