Go 1.26 par noklusēto atkritumu savācēju kļūst Green Tea — algoritms, kas skenē 8 KiB lielas atmiņas lapas, nevis staigā pa atsevišķiem objektiem. Go komanda savā emuāra ierakstā lēš, ka programmās, kuras stipri noslogo savācēju, GC izmaksas krītas par 10–40%. Kurš negrib, var atgriezties pie vecā uzvedības ar karodziņu GOEXPERIMENT=nogreenteagc būvēšanas laikā.
Green Tea Go 1.25 bija eksperimentāls; tagad tas ir ieslēgts pēc noklusējuma un jau darbojas Google produkcijā. Lai saprastu, kāpēc maiņa bija vajadzīga, jāsāk ar to, kur vecajam savācējam sāp.
Kur vecajam savācējam sāp
Go izmanto mark-sweep savākšanu: tas izseko norāžu grafu, atzīmē sasniedzamos objektus un pēc tam atbrīvo pārējos. Aptuveni 90% no savācēja izmaksām aiziet marķēšanai un tikai kādi 10% slaucīšanai. Problēma slēpjas tajā, kur marķēšanas laiks pazūd: vismaz 35% no tā CPU vienkārši stāv un gaida piekļuvi atmiņai.
Cēlonis ir grafa pārstaigāšana. Kad savācējs seko norādēm, tas lec pa atmiņu neparedzami — viens objekts šeit, nākamais pavisam citā vietā. CPU kešatmiņa šādu piekļuvi nevar iepriekš paredzēt un sagatavot. Go komanda to salīdzina ar braukšanu pa pilsētas ielām: motora jauda maz palīdz, ja nekad nesanāk uzņemt ātrumu.
Neatkarīgi no tā, cik ātrs ir dzinējs, tu nekad nedabū iespēju izkustēties.
Šī problēma ar gadiem paliek asāka. Mūsdienu serveros ir arvien vairāk kodolu, atmiņas joslas platums uz vienu kodolu sarūk, un NUMA arhitektūrā piekļuves cena atšķiras atkarībā no tā, kurš kodols pie kuras atmiņas ķeras. Vecais algoritms visu šo aparatūru neizmanto.
Ko dara Green Tea
Green Tea pamatideja ir īsa: strādā ar lapām, ne objektiem. Vietā, kur agrāk darba sarakstā glabājās atsevišķi objekti, tagad tur nonāk 8 KiB lielas lapas. Katram objektam uz lapas savācējs tur divus bitus — vai uz to norāda kāda norāde (“seen”) un vai tas jau ir noskenēts (“scanned”).
Otra maiņa ir rindas kārtība. Vecais savācējs ņēma objektus steka principā (pēdējais iekšā, pirmais ārā). Green Tea lapas apstrādā rindā (pirmais iekšā, pirmais ārā), tāpēc uz vienas lapas paspēj sakrāties vairāki objekti, pirms tā tiek skenēta. Rezultāts: mazāk, bet garāki secīgi gājieni pār atmiņu. Go emuāra piemērā vecais algoritms vienam grafam prasīja septiņus lēcienus pa kaudzi, Green Tea to pašu izdarīja četros garākos gājienos. Jo lielāka kaudze, jo stiprāks efekts.
Kur iesaistās AVX-512
Tāpēc, ka objekti tagad sakārtoti blīvi pa lapām, savācējs var izmantot vektoru instrukcijas, ko iepriekš objektu haosā nevarēja. Uz jaunākiem x86 procesoriem (Intel Ice Lake, AMD Zen 4 un jaunāki) Green Tea skenē 64 baitus vienā piegājienā ar AVX-512.
Skenēšanas kodols paņem lapas “seen” un “scanned” bitus — pateicoties AVX-512 reģistru 512 bitu platumam, vesela lapa ietilpst divos reģistros. Bitu izplešanai no viena bita uz objektu līdz vienam bitam uz vārdu izmanto VGF2P8AFFINEQB, Galois lauka instrukciju, kuru Go komanda sauc par galveno varoni. Vektorizācija dod vēl aptuveni 10% mazāku GC CPU slodzi papildus pamata algoritmam.
Cik tas dod praksē
Skaitļi ir atkarīgi no slodzes. Biežākais uzlabojums ir ap 10% mazāk laika savācējā; ja programma savācējā pavada 10% laika, tas nozīmē 1–4% mazāku kopējo CPU patēriņu. Datubāzēm, kešiem un serveriem ar koku vai grafu struktūrām ieguvums ir lielāks. Ģeodatubāzes tile38 mērījumos GC slodze kritās par 35%, L1 un L2 kešatmiņas promgājieni mikrotestos samazinājās uz pusi, un uz daudzkodolu mašīnām Go 1.26 apskatā minēts 10–50% GC CPU ietaupījums.
Ne visur aina ir rožaina. DoltHub 2025. gada septembrī izmēģināja toreiz eksperimentālo Green Tea un dabūja neitrālu rezultātu — mazāk GC ciklu, bet vairāk CPU uz katru ciklu. Go komanda šo “retāk, bet dārgāk” problēmu izlaboja pirms galīgā laidiena. Slodzēm, kur uz vienas lapas jāskenē tikai viens objekts, Green Tea var būt pat sliktāks par veco algoritmu, lai gan jau 2% aizpildītas lapas dod uzlabojumu.
Kā ieslēgt un ko vēl nes 1.26
Ieslēgt neko nevajag — Go 1.26 Green Tea ir noklusējums. Ja kāda slodze regresē, atgriezties pie vecā savācēja var ar GOEXPERIMENT=nogreenteagc. Kļūdas un mērījumus Go komanda joprojām vāc GitHub problēmā #73581, tāpēc pirms lēmuma ražošanā ir vērts salīdzināt savus pašu profilus.
Green Tea nav vienīgā veiktspējas izmaiņa. cgo izsaukumi kļuva ap 27% ātrāki, jo no tiem izņemts syscall stāvoklis; mazu objektu izdalīšana paātrināta līdz 30% ar izmēram pielāgotām rutīnām; io.ReadAll ar eksponenciālu bufera augšanu ir aptuveni uz pusi ātrāks; un jaunā errors.AsType ģenērika strādā ap trīsreiz ātrāk par reflection balstīto errors.As. Valodas pusē new tagad pieņem izteiksmes: p := new(42) uzreiz atgriež norādi uz inicializētu vērtību.
Komentāri
Šim rakstam vēl nav komentāru. Esi pirmais, kurš dalās ar savu viedokli.