К. Касперски - Техника оптимизации программ, Эффективное использование памяти (1127752), страница 18
Текст из файла (страница 18)
Загрузим полученный файл в ч"Типе и, дождавшись появления диаграммы "Ног Ярой", дважды щелкнем мышкой по самому высокому прямоугольнику, соответствующему, как мы уже знаем, функции дев реев, в которой программа проводит ббльшую часть своего времени. Теперь, удерживая левую кнопку мыши, выделяем тот фрагмент, который мы хотим проанализировать (логичнее всего выделить всю функцию Чее рвиа ЦЕЛИКОМ) И ОТЫСКИВВЕМ На ПВНЕЛИ ИНСТруМЕНТОВ ТахуЮ ДОВОЛЬНО затейливую кнопку с изображением учителя, облаченного в красную рубаху, и коричневой ученической доски на заднем фоне. Нажмем ее.
Инструктор Глава 1 запросит сведения о файле, которым компилировалась данная программа. На выбор предоставляется пта!ге-файл, файл препроцессора и, конечно же, как и во всякой профессиональной программе, возможность ручного ввода. Поскольку никаких особенных опций компиляции мы не задавали, а шайефайла у нас все равно нет, мы выбираем опцию Мапва! Евтгу и нажимаем кнопку ОК. Пропускаем появившееся на экран ругательство — 'ГЧо воцгсе орГюп чгеге зресгТгед" ("Искодньче опции не были заданы') и жмем кнопку ОК еще раз. Профилировщик 11Тппе тут же начнет анализ и буквально через несколько секунд не без удовлетворения сообщит; "Т!4еге аге 9 гесошптепг1аьюпз Ыепббед Гог йе зе!есгед соде.
ОоцЫе-С!!814 оп апу адчсе Гог агЫЫопа! шГоппабоп" Г"В выделенном коде распознано девять «рекомендатезьных гиаблонов». Для получения дополнительной информации дважды щелкните по любому совету'). Оказывается„в нашей уже далеко "не хило" оптимизированной программе все еще присутствует, по меньшей мере, девять слабых мест! И не просто слабых, а настолько слабых, что они обнаруживаются тривиальным шаблонным поиском! Ну и мы "молодцы", — нечего сказать! Ладно, кончаем заниматься самобичеванием, а лучше посмотрим, что этот умник 11Тцпе тут нагородил.
Рекомендации инструктора записаны прямо поверх кода программы и первое замечание выглялит следующим образом: 84 ГОХ (Ь = 0; Ь <= 1ЕПчхпг Ь»Ы х»= *11пп *> (1ШЮР»ча» Ш 4 85 тЬе 1оор ап 1впе 84 сап Ье пппо11ев 4 Ьгпее "Цикл в строке 84 может бьчть развернут четыре раза". Глупый 41Тцпе! Этот цикл исполняется всего лишь раз за весь прогон программы и особой "погоды" его оптимизация не сделает! Кстати, а что такое "развертка циклов" и как ее осуществить? Дважды щелкаем по выделенной строке, и Инструктор имеет честь сообщить нам следующее: "Каким образом оформить эти сообщения? В кавычках? Курьер? Или?" 1люр виго!!!вя Ехашр1ез: С, Ронгап, )ача* Т!4е 1оор сон!а!пз !пзггцсг!опз йаг до пог а!!очч еГбс!епг гпзгпзсйоп зс!1едц!!пя апд ра!г!пя. Т!ге !пзгпзсг!опз аге Ге4ч ог !гаче дерегЫепсгез йаг ргочЫе 1!п1е зсоре Гог йе согпр!1ег го зс!зедц!е йегп !и зцс!4 а пзаппег аз со гпа!ге орйпа! цае оГ йе ргосеввогз гпп!11р1е р!ре1!пез, Аз а гезц!Г, ехГга с!ос!4 сус1ез аге пеедед Го ехесцГе йезе !пзггпсг!опз.
Профипировка программ 77 А!Ьчсе !)пго!1 йе !оор аз зияаезгег! Ьу г1зе соас!и Сгеаге а !оор гЬаг сопгашв пюге !пзггисбопз, Ьиг ьв ехесигед Гешег Витек 1Г йе инго!!шя Гасгог зияяезгег! Ьу 1!те соасЬ гв пог арргорпаге, изе ап игго1!!пя Гасгог! Ьаг гв пюге арргорпаге. То впгоП йе 1оор, до йе Го!!овчпд: - Керйсаге йе Ьог!у оГ йе !оор г!те гесопшзепдес$ пшпЬег оГ !!п1ез. - А4изг йе !пдех ехргезз!опз го геГегепсе зиссеза!че аггау е1ешепгк - Ад1изг йе 1оор сопгго! згагешепгк Кезв1г: - !псгеазез гЬе пипзЬег оГ пзасЬ!пе !пзггисг!опз яепегагед !пзЫе йе 1оор.
- РгочЫез пюге зсоре Гог йе сошр11ег го геогдег апд зсЬег1и!е шзггисг!опз зо йаг г!теу ра1г апд ехесиге з1пзи1гапеоиз!у !и йе ргосеззог'з р1ре!!пеа - Ехесигез йе !сор Гевег йпез. Сав бои: Ве аччаге йаг Ьтсгеазйзя йе пишЬег оГ !паггисгюпз тч11!т1п йе 1оор а!зо шсгеазез йе гея!агег ргеззиге. В переводе на русский язык все вышесказанное будет звучать приблизи- тельно таким образом; Разворачивание цикла: Данный цикл содержит инструкции, которые не могут быть эффективно силанированы и распараллелены процессором, поскольку они малочисленны (то бишь кворума мы здесь не наберем — К.
К.) или содержат зависимости, что сужает возможности компилятора в их группировке для достижения наиболее оптимального использования конвейеров процессора. В результате, на выполнение этих инструкций расходуется значительно большее количество циклов. Советг Разверните цикл, согласно советам "Учителя". Создайте цикл такой, чтобы он содержал больше инструкций, но исполнялся,иеньшее количество раз. Если степень развертки, рекомендуемая "Учителем", кажется вам неподходящей, используйте более подходяиГую степень.
7В Глава з ллля развертки цикла сделайте следующее: — продублируйте тело цикла соответствующее количество раз; — скорректируйте ссылки на продублированные элементы л[ассива; — скорректируйте условие цикла. Результат: — увеличивается количество машинных инструкций внутри цикла; — появляется место, где 'развернуться" колтилятору для переупорядочивания и планирования потока инструкций так, чтобы они спаривались и выполнялись параллельно в конвейерах процессора; — выполнение цикла занимает меньшее время. Лр едиот ерезкениео Знайте, что увеличение количества инструкций в теле цикла влечет за собой увеличение "регистрового давления".
Согласитесь, весьма исчерпывающее руководство по развертке циклов! Причем, если вам все равно не понятно как именно разворачиваются циклы, МОЖНО ЩЕЛКНУТЬ ПО ССЫЛКЕ "ЕХаПЗР[ЕЗп [ПРИМЕРЫ) И УВИДЕТЬ КОНКРЕтНЫй пример "продразверстки" на С, лача или Еопгап. Давайте выберем язык С и посмотрим, что нам еще посоветует профилировщик а[Типе: Оггаьпа1 Сода сог[1 Оз г<п; а[г1 = с[11 ! О[оьап<1гад Сода гоп[1=0р 1<п-[паз[! а+=31 а[11 = с[11 [ а[а<11 = с[1<11; а[1<21 = с[1ь2[з гоп[юг < и; а[11 = с['г[; Тем не менее, мы этот цикл разворачивать не будем и пойдем дальше.
Совет номер два вновь рекомендует развернуть тот же самый цикл, но уже находящийся внутри цикла чл 1 . Поскольку этот цикл получает управление лишь при удлинении перебираемого пароля на один символ (что происходит прямо-таки скажем не часто), он, как и предыдущий, не оказывает практически никакого влияния на производительность, а потому рекомендацию по его развороту мы отправим в /деч/ппП. Профипировка программ 29 Совет номер три придирается к с виду безобидной конструкции р+, увели- чивающей переменную р на единицу: (7.Н- ( хг ()речсцп) ) 116 рекс)(р)='! '( реч)(о+1) О( 1епдСЬ+со х= -17 117 пв 119 зго 121 122 ГОХ (Ь = О( Ь <= 1ЕкдСЬ) Ь+е) х -~= *(хос *) ((хес)речс( + Ы ( ТЬе !оор ччйозе нн1ех 19 !псгетепгед а( !1пе ! !4 вЬоп!д Ье 1пгегсЬапяед чдй йе 1оор ччЬозе !п(1ех гв шсгегпеп(ед аг 1!пе 121, Гог тоге еГГ!с)епг гпепюгу ассеьв 1оор 1и!его!)авйе) моора чдй !пдех чапаЫев геГегепс!пя а то!11-д!пзепв!опа! аггау аге немед.
ТЬе оп1ег )п чгЫОЬ йе )пдех чапаЫез аге шсгегпеп(ед санаев оцг-оГ-ве()пенсе апау геГегепс!пя, юц!1!пя ш тапу дага сасЬе т!9ВЕЗ. ТЬга шсгеавев йе 1оор ехесщюп типе. Аду!се) !эо йе ГОПозчшя: - С11апбе йе зев)цепсе оГ117е аггау д!пзепз!опв !п йе аггау дес!агабоп. - 1п(егсЬапяе йе !оор сон!го! зга(етепгв. Кеав1!1 ТЬе огдег ш чгЬ!ОЬ йе аггау е!епзепга аге геГегепсед 19 гпоге вес)ценна!. Гечег даГа сасЬе т!взев оссцг, яяп)Т)сап(1у гедцс!пя йе !оор ехеспгюп гцпе. 'Для достижения более эффективного доступа [к памяти/ цикл, чей индекс увеличивается в строке 114, должен бьипь заменен циклом, чей индекс увеличивается в строке 121?!" Инструктор, судя по всему или "пьян", или от перегрева процессора слегка "спятил".
Это вообще разные циклы. И индексы у них разные. И вообще они не имеют друг к другу никакого отношения, причем цикл, расположенный в строке 121, исполняется редко, так что совсем не понятно, что это профилировщик )(Типе к нему так пристал?! Может быть, дополнительная информация от Инструктора все разьяснит? Дважды щелкаем по строке 114 и читаем: во Глава 1 Совет: Сделайте следующее: — измените последовательность измерений массивов в их обьявлении; — поменяйте местами "измерения" управления ((икла (подразумевается; сделайте либо то, либо это, но ни в коел( случае ни то и другое вместе — ина~е "минус на минус даст плюс" и вы получите тот же са- мьзй результат — К.
К.). Результат: Порядок, в которолз обрабатываются элементы массива, станет более после- довательным. Меньи(е кэш-промахов будет происходить, от чего врелзя выпол- нения цикла значительно сократится. Какие многомерные массивы? Какие кэш-промахи? Здесь у нас и близко нет ни того, ни другого! Судя по всему, мы столкнулись с грубой ошибкой Инструктора [шаблонный поиск дает о себе знать!), но все же не поленимся и заглянем в предлагаезмый Инструктором пример, памятуя о том, что всегда в первую очередь следует искать ошибку у себя, а не у окружающих. Быть может, это мы чего-то недопонимаем.
Орпзелаеа Соое 1пп ь[2001(1201з чола Зпр112(1пС *а( ( Огзэапа1 Сапе зпп Ы2001["120(з поза апр117(спо *а( 1па 3., спг зпп апепрз Гог (з = Оз 1 < 120з 1ею гоп (З = Оз 1 < 200( гог (З = Оз З < 2002 О+Ы гог (з = Оз а < 120(за+1 ь(01 (11-Ыз( (з]+а[2 Ь(01 (з[=Ь(11 (з(+а [2*01 з Перестановка циклов: Здесь наблюдаются вложенные циклы с индекснылзи перел(еянылпц обри(цаюи(и- мися к многомерным лзассивам. Порядок, в контрам увеличиваются ю(дексиые переменные, приводит к несвоевременному обрзт(ению к л(ассивалц и кпк след- ствие этого — множественным кэш-промпхам. В результате увеличивпется орел(я выполнения цикла.
Профилировка программ Ну аот, все правильно. Приводимый профилировщиком ч(Топе фрагмент кода наглядно демонстрирует, что двухмерные массивы лучше обрабатывать по строкам, а не столбцам !см. главу 3). Но ведь у нас нет двухмерных массивов, а — стадо быть — и слушаться Инструктора в данном случае не надо.