Кіріспе

Циклдік трансформация техникасы

Циклді ашу, сондай-ақ циклді жаю деп те аталады, бұл бағдарламаның орындалу жылдамдығын оның бинарлық көлемі есебінен оңтайландыруға бағытталған циклдік трансформация әдісі, бұл кеңістік-уақыт айырбасы деп аталады. Трансформацияны бағдарламашы немесе оңтайландырушы компилятор қолмен жүзеге асыруы мүмкін. Қазіргі заманғы процессорларда циклді ашу көбінесе нәтижесіз болады, себебі код көлемінің ұлғаюы кэштен деректердің жоғалуына әкелуі мүмкін; cf. Даффтың құрылғысы. Циклді жаюдың мақсаты – циклді басқаратын нұсқауларды азайту немесе жою арқылы бағдарламаның жылдамдығын арттыру, мысалы, көрсеткіш арифметикасы және әр итерациядағы «цикл соңы» тексерулері; тармақталу салдарынан туындайтын кешігулерді азайту; сондай-ақ жадтан деректерді оқу кешігуі сияқты жасырын кідірістерді жою. Бұл есептеу шығындарын жою үшін циклдар ұқсас тәуелсіз операторлардың қайталама тізбегі ретінде қайта жазылуы мүмкін. Циклді ашу белгілі бір формалды тексеру техникаларының, әсіресе шектелген модельді тексерудің бір бөлігі болып табылады.

Артықшылықтар

"Тығыз" циклдердегі қосымша шығындар көбінесе массивтегі келесі элементке көрсеткішті немесе индексті жылжыту нұсқауларынан (көрсеткіш арифметикасы), сондай-ақ "цикл аяқталуы" тексерулерінен тұрады. Егер оңтайландырылатын компилятор немесе ассемблер әрбір жеке сілтемеленген массив айнымалысына қадамдарды алдын ала есептей алса, оларды тікелей машиналық код нұсқауларына енгізуге болады, демек, орындалу кезінде қосымша арифметикалық операциялар қажет болмайды. Бағдарлама көлемінің ұлғаюынан туындаған өнімділік төмендеуін орындалатын нұсқаулардың азаюы толықтыра алса, айтарлықтай пайда алуға болады. Тармаққа байланысты кешігу азаяды. Циклдегі операторлар бір-біріне тәуелсіз болса (яғни, циклде ертерек орындалған операторлар келесі операторларға әсер етпесе), операторлар параллель түрде орындалуы мүмкін. Массив элементтерінің саны компиляция уақытында белгісіз болса (мысалы, Дафф құрылғысындай), динамикалық түрде жүзеге асырылуы мүмкін. Оңтайландырылатын компиляторлар кейде бұл өзгертуді автоматты түрде немесе сұраныс бойынша жасайды.

Кемшіліктер

Бағдарламалық кодтың көлемінің артуы, әсіресе кіріктірілген қосымшалар үшін жағымсыз болуы мүмкін, сонымен қатар нұсқаулар кэшінің қателіктерінің көбеюіне әкелуі мүмкін, бұл өнімділікке кері әсер етеді. Егер оптимизациялайтын компилятор бұл өзгерісті автоматты түрде жасамаса, кодты түсіну қиындауы мүмкін. Егер цикл ішіндегі код функцияларды шақыратын болса, циклды ашу мен функцияны ішкі кодқа енгізуді бірге қолдану мүмкін болмайды, себебі кодтың көлемі тым артық көбеюі мүмкін. Сондықтан, бұл екі оңтайландырудың арасында таңдау жасау қажет болуы мүмкін. Сонымен қатар, уақытша айнымалыларды сақтау үшін бір итерацияда қолданылатын регистрлердің саны артуы мүмкін, бұл өнімділікті төмендетуі мүмкін, бірақ бұл мүмкін болатын оптимизацияларға байланысты. Көбінесе өте кішкентай және қарапайым код болмаса, тармақтарды қамтитын ашылған циклдар рекурсиядан да баяу жұмыс істейді.

Статикалық/қолмен бұранданы ашу

Қолмен (немесе статикалық) циклды ашу, бағдарламашының циклды талдап, оның қайталануларын циклдің жұмысын азайтатын нұсқаулар тізбегіне түрлендіруімен жүзеге асырылады. Бұл компилятор жасап беретін динамикалық ашудан өзгеше.

Динамикалық ақтау

Бұрауды ашудың пайдасы көбінесе массивтің өлшеміне байланысты болады, ал ол көбінесе орындалу уақытына дейін белгісіз болуы мүмкін. JIT компиляторлары (мысалы) "стандартты" бұрау тізбегін шақыруға немесе әрбір элемент үшін жеке нұсқаулардың (салыстырмалы түрде қысқа) тізбегін жасауға шешім қабылдай алады. Бұл икемділік – циклды ашу контекстінде статикалық немесе қолмен оңтайландыруға қарағанда уақытында оңтайландырудың бір артықшылығы. Мұндай жағдайда, n-нің салыстырмалы түрде кіші мәндерінде үнемдеу әлі де маңызды болуы мүмкін, бұл бағдарламаның көлемін (стандартты кітапхананың бір бөлігі ретінде бір рет қосылуы мүмкін) өте азға (болса да) ұлғайтуды қажет етеді. Ассемблер тілінде бағдарламалайтындар (оның ішінде оңтайландырушы компиляторларды жазатындар) да тиімді тармақ кестелеріне ұқсас әдіс қолданып, динамикалық циклды ашу әдісінен пайда көре алады. Бұл жағдайда, егер белгілі бір массивтегі сілтемелі кез келген өрістің максималды ығысқануы машиналық нұсқаулармен көрсетілетін максималды ығысқанудан кем болса, артықшылық ең жоғары болады (егер одан асып кетсе, құрастырушы ескертеді).