Loop Peeling — siklning bir yoki bir nechta boshlang‘ich yoki oxirgi iteratsiyasini alohida kodga chiqarish transformatsiyasi. Bu qolgan asosiy siklda maxsus shartni yo‘qotish, alignmentni ta’minlash yoki optimallashtirish uchun bir xil holat yaratadi.
Ajratilgan iteratsiyalar
for i=0..n-1 ichida if (i==0) bo‘lsa, birinchi iteratsiya alohida bajarilib, qolgan sikldan branch olib tashlanadi. Vectorizer pointer alignmentgacha bo‘lgan bir necha scalar iteratsiyani prologue sifatida peel qilib, keyin aligned SIMD loopni ishga tushirishi mumkin.
Semantik shartlar
Peeling zero yoki kichik trip countni to‘g‘ri boshqarishi kerak. Birinchi iteratsiyani shartsiz chiqarish n=0 holatida xato bajarilish yaratadi, shuning uchun guard qo‘yiladi. Induction variable qiymati, overflow semantics, break/continue va exception tartibi aynan saqlanishi zarur.
Boshqa usullardan farqi
Loop-carried dependence peelingga odatda to‘sqinlik qilmaydi, chunki original tartib saqlanadi, ammo boundary state asosiy loopga to‘g‘ri uzatilishi kerak. Ko‘p iteratsiyani peel qilish code size va instruction cache xarajatini oshiradi. Profitability modeli keyingi loopdagi yutuqni shu xarajat bilan solishtiradi.
Foydalilik
Peeling unrollingdan farq qiladi: unrolling body nusxalarini asosiy loopning har qadamiga joylashtiradi, peeling esa cheklangan iteratsiyalarni loop tashqarisiga chiqaradi. Prologue/epilogue vector loop tail handling bilan birga ko‘rinishi mumkin.
Tekshiruv
Tekshiruv n=0, n=1, peel countdan kichik va katta qiymatlarni qamraydi. Har original iteration aynan bir marta bajarilishi trace orqali tasdiqlanadi. Address sanitizer boundary xatolarini, compiler optimization remark esa peelingdan keyin branch yoki alignment taxmini ishlatilganini ko‘rsatadi.
Loop Peeling bo‘yicha tahlil natijasi faqat yakuniy xulosa bilan emas, uni hosil qilgan IR versiyasi, target xususiyatlari va qo‘llangan taxminlar bilan birga saqlanadi. Compiler passlari ketma-ket o‘zgarganda oldingi natija avtomatik ravishda haqiqiy deb olinmaydi: tegishli dependencylar invalidatsiya qilinib, zarur qism qayta hisoblanadi. Debug rejimida asosiy invariant buzilgan nuqta va undan oldingi transformatsiya qayd etiladi; release rejimida esa tekshiruvlarning arzon qismi qoldiriladi. Shu yondashuv nazariy jihatdan qonuniy qoida implementatsiya xatosi yoki noto‘g‘ri cost model sabab zararli qarorga aylangan holatni ajratishga yordam beradi.
Kengaytirilgan jihatlar
Peeling loop invariantni kuchaytirishi mumkin. Masalan, linked-list traversalning birinchi node’i null emasligi tashqi guard bilan tasdiqlansa, qolgan loopda ayrim null checklar redundant bo‘ladi. Profile ko‘rsatgan common first-iteration branch alohida hot pathga chiqarilishi ham mumkin. End peeling epilogue shartini soddalashtiradi, lekin exit value va induction variable post-loop qiymati original bilan teng qoladi. Compiler transformatsiyadan keyin dominator tree, loop info va scalar evolution ma’lumotlarini yangilashi yoki invalidatsiya qilishi kerak. Eski metadata keyingi passga noto‘g‘ri trip count berishi mumkin.
Peel count compile-time constant bo‘lishi yoki alignmentgacha runtime hisoblanishi mumkin. Runtime count original trip countdan min bilan cheklanadi. Profilingda peeled prologue va main loop alohida block frequency oladi; aks holda keyingi scheduler sovuq prologni issiq deb baholashi mumkin. Code size limiti ko‘p nested loop peelingini to‘xtatadi.
Peeling remark ajratilgan iteratsiyalar soni, asosiy loop uchun hosil bo‘lgan alignment yoki branch faktini ko‘rsatadi. Shu dalil transformatsiya maqsadini tekshiradi.
Bog‘liq tushunchalar
loop unrolling, loop vectorization, induction variable, prologue loop, alignment, loop transformation