Վերադառնալ
Փորձնական փաթչ Go-ի netip-ում չեղարկում է բայթերի վերադասավորումը IPv4-ը IPv6-ի փոխարկելիս
SiTech AI Team2 րոպե ընթերցում

Փորձնական փաթչ Go-ի netip-ում չեղարկում է բայթերի վերադասավորումը IPv4-ը IPv6-ի փոխարկելիս

Փորձնական կոմպիլյատորի վերաշարադրումը Go-ի netip.AddrFrom16(ip.As16()) նախշը վերածում է ներքին դաշտի ուղիղ պատճենման և արտադրում է նույն կարճ ասեմբլերը, ինչ 0,88 ns-անոց ստանդարտ գրադարանի լուծումը։

Ինչու է փոխարկման նախշը դանդաղ

Go-ի netip.Addr-ը տրամադրում է Unmap() մեթոդ, որը IPv4-ով ներկայացված IPv6 հասցեից վերադարձնում է բացված IPv4 հասցեն։ Հակառակ գործողության համար չկա Map() կամ To6() մեթոդ։ Go-ի մենթեյներները հրաժարվել են այն ավելացնելուց և օգտվողներին ուղղորդում են դեպի netip.AddrFrom16(ip.As16())՝ հույսով, որ կոմպիլյատորը դա կօպտիմալացնի։

Ներսում netip.Addr-ը IP հասցեն պահում է որպես 128-բիթանոց արժեք և օգտագործում է լրացուցիչ դաշտ՝ դրա ընտանիքը և գոտին կոդավորելու համար։ To6()-ի ստանդարտ գրադարանի իրականացումը կարող էր փոխել այդ դաշտը IPv4 հասցեների համար։ Իսկ արտաքին օգնականը հակառակը՝ պետք է հասցեն վերածի 16-բայթանոց զանգվածի և վերադարձնի հետ։

Բենչմարկի արդյունքները

Go 1.27.1-ի Linux-ում և AMD-ի Ryzen 5 5600X 6-միջուկանի պրոցեսորի վրա անցկացված բենչմարկներում ստանդարտ գրադարանի լուծումը գործողության համար պահանջել է 0,8775 ns։ Անվտանգ օգնականը պահանջել է 7,137 ns, իսկ անանվտանգ իրականացումը, որը նույն ներքին վիճակին հասնում էր proxy-ի միջոցով,՝ 0,8682 ns։ Այդ պատճառով օգնականը մոտավորապես ութ անգամ դանդաղ էր։

Ստանդարտ գրադարանի և անանվտանգ տարբերակների ասեմբլերները գրեթե նույնական էին։ Երկուսն էլ ստուգում էին հասցեի ընտանիքը և IPv4-ի մշակման ժամանակ փոխում էին ներքին ընտանիքի արժեքը։ Անվտանգ օգնականը ավելի շատ հրահանգներ էր գեներացնում, քանի որ հասցեն դասավորում էր 16-բայթանոց զանգվածում, պատճենում էր զանգվածը և նորից բացում։ Go 1.26.8-ի դրությամբ կոմպիլյատորը այդ հաջորդականությունը չէր հեռացնում։

Կոմպիլյատորի մակարդակի փորձ

Փորձը հենց netip.AddrFrom16(ip.As16()) նախշը վերաշարադրում է կոմպիլյատորի noding փուլի ընթացքում։ Այն կանչերը փոխարինում է netip.Addr կառուցվածքով, որը պատճենում է բնօրինակ հասցեն և վերագրում IPv6 ընտանիքի արժեքը։ Վերաշարադրումը պետք է կատարվի noding-ի ընթացքում, քանի որ ավելի վաղ տիպերի ստուգման փուլն արգելում է կառուցվածքի չարտահանված դաշտերին հասանելիությունը։

Մոդիֆիկացված build-ը վերաշարադրմամբ գեներացնում էր նույն կարճ ասեմբլերը, ինչ ուղիղ իրականացումը, և թեստերը հաջողությամբ անցան net/netip-ի և օգնական փաթեթի համար։ Վերլուծությունը նշում է, որ Go-ի մենթեյներները քիչ հավանական է, որ համաձայնեն այս մոտեցմանը, քանի որ այն կախված է netip.Addr-ի ներքին դասավորությունից և noder-ին ավելի շատ պատասխանատվություն է դնում, քան տիպերի ստուգված շարահյուսական ծառի հավատարմորեն թարգմանելը։

Առաջարկվող SSA օպտիմիզացիա

Ավելի ընդհանուր մոտեցումը որպես թիրախ ընտրում է կոմպիլյատորի ընդհանուր SSA փուլը, մասնավորապես memcombine փասը։ Առաջարկվող վերաշարադրման կանոնները բեռնումները վերահասցեավորում են հիշողության տեղափոխումների միջոցով, պահված արժեքները փոխանցում են հետագա բեռնումներին և չեղարկում բայթերի փոխանակման գործողությունների զույգերը։

Հասցեի յուրաքանչյուր 64-բիթանոց կեսի համար այս ձևափոխությունները խուսափում են ժամանակավոր զանգվածից, դրա պատճենից և ավելորդ հիշողության հասանելիությունից։ Ավելի բարձր կեսի փոխանցումը նույնպես հնարավոր է պահման գործողության միջոցով դեպի հարևան, չծածկվող հասցե։ Պարզեցումից հետո յուրաքանչյուր ելքային կես դառնում է համապատասխան մուտքային կեսի պատճենը, ինչը հասցեի տվյալները թողնում է անփոփոխ և դնում է անհրաժեշտ ընտանիքի արժեքը։

SSiTech

SiTech — AI-ով հզորացված վեբ մշակում

Ստեղծում ենք արագ ու ժամանակակից կայքեր և AI-ը ներդնում իրական բիզնես գործընթացներում։ Ունե՞ք նախագիծ կամ հարց։ Ուրախ կլինենք օգնել։