К. Касперски - Техника оптимизации программ, Эффективное использование памяти (1127752), страница 10
Текст из файла (страница 10)
И такой способ есть! Достаточно поместить перед естзс одну из команд упорядоченного выплллеиил. Команды упорядоченного выполнения начинают обрабатываться только после схода с конвейера последней предшествующей ей неупорядоченной команды и, до тех пор пока команда упорядоченного выполнения не завершится, следующие за ней команды мирно дожидаются своей очереди, а не "лезут как толпа дикарей" вперед на конвейер. Подавляющее большинство команд упорядоченного выполнения — зто привилегированные команды (например, инструкции чтения/записи портов ввода/ вывода), и лишь очень немногие из них доступны с прикладного уровня. В частности, к таковым принадлежит инструкция идентификации процессора Ерш б. Многие руководства (в частности и Агнер Фог в своем руководстве "Но1у го оргппкее Гог !1зе Реп!щи 1апз!!у оГ ппсгоргосевеоге" и технический документ "()з!пя г)1е К(уТБС !пе!гас!!оп 1ог РегГогшапсе Моп!Ео1!пяя от корпорации (ше!) предлагают использовать приблизительно такой код (листинг !.1О).
Глава 1 предыдулме машинные инструкции гарантированно совши с конвейера и потому никак не могут повлиять на результаты на»ш»х заиеров вызываем инструкции ЕОТЕС, которая возврашает в регистре ЕАХ младшее двойное слово текушего значения Т»ше 5башр Соцп»е» а ЕСТ5С МОУ !с1осх],ЕАХ сохраняем полученное только что значение в переменной с1осх // // проьилируеьмй код // ... т — здесь исполняется провилируеьей код ХОЕ ЕАХ, ЕАХ село еше раз выполняем команду СРО1О, чтобы все предыдущие инструкции гарантированно успели покинуть конвейер вызываем инструкцию ЕОТ5С для чтения нового значение т1ие зсашр соцп» РОТ5С 555 ЕАХ, !с1ось,' вычисляем разность второго и первого замеров, тем самым определяя реальное время выполнения профьтируемого Фрагмента кода К сожалению, даже этот, официально рекомендованный, код все равно не годится лля измерения времени выполнения отдельных инструкций, поскольку полученный с его помощью результат представляет собой полное время выполнения инструкции, т.
е. ее латентность, а отнюДь не проиускную способность, которая нас интересует больше всего. (Кстати, и у !пге!, и Агнсра Фога есть одна грубая ошибка — в их варианте программы перед инструкцией СРСТО отсутствует явное задание аргумента, который эта инструкция ожидает "увидеть" в регистре елх. А поскольку время се выполнения зависит от аргумента, то и время выполнения профилируемого фрагмента не постоянно, а зависит от состояния регистров на входе и выходе. В предлагаемом мною варианте (см, листинг!.1О) инициализация Профилировка программ вхх осуществляется явно, что страхует профилировщик от всяких там наве- денных эффектовд Имеется и другая проблема, еше более серьезная, чем первая. Вы помните постулат квантовой физики, сводящийся к тому, что всякое измерение свойств объекта неизбежно вносит в этот объект изменения, искажающие результат измерений? Причем, эти искажения невозможно устранить простой калибровкой, поскольку изменения могут носить не только количественный, но и качественный характер.
Если профилируемый код задействует те же самые узлы процессора, что и команды автзс/сгззс, время его выполнения окажется совсем иным, нежели в действительности! Никаким ухищрениями нам не удастся достигнуть точности измерений до одного-двух тактов! Поэтому, минимальный промежуток времени, которому еи!е можно верить, составляет, как показывает практика и личный опыт автора, по меныие мере пятьдесят-сто тактов.
Отсюда следствие: штатными средствами процессора измерять время вы- полнения отдельных команд невозможно. Аппаратная оптимизация На мгновение отвлечемся от компьютеров и зададимся вопросом: можно ли с помощью обычной ученической линейки измерить толщину листа принтерной бумаги? На первый взгляд, тут без штангенциркуля ну никак не обойтись Но, если взять с полсотни листов бумаги и плотно сложить их друг с другом; вы уже поняли куда я клоню? Пусть погрешность измерения толщины образовавшегося "кирпича" бумаги составит +! мм, тогда — точность определения толщины каждого отдельно взятого листа будет не хуже чем ч-0,02 мм, что вполне достаточно для большинства повседневных целей! Почему бы не применить эту технику для измерения времени выполнения машинных команд? В самом деле, время выполнения одной команды так мало, что просто ничем его не измерить (см, разд.
"г1еточность измерений" этой главы), но если мы возьмем сто или даже сто тысяч таких команд, то... Но, увы! Машинные команды ведут себя совсем не так, как листы бумаги. Неоднородность конвейера приводит к тому, что зависимость между количеством и временем выполнения команд носит ярко выраженный нелинейный характер. К тому же, современные процессоры слишком умны, чтобы воспринимать переданный им на выполнение код буквально. Нет! Они подходят к этому делу весьма творчески.
Вот, допустим, встретится им последовательность команд меч аьх, ы чоч ьхх, ы меч ахх, т, каждая из которых помещает в регистр кьх значение "!". Думаете, процессор как полный недоумок испол- эв Глава 1 нит все три команды? Да как бы не так! Поскольку результат двух первых присвоений никак не используется, процессор отбросит зти команды как ненужные, затратив время лишь на их декодирование, и ощутимо сэкономит на их выполнении! Оптимизация программного кода, выполняемая процессором на аппаратном уровне, значительно увеличивает производительность системы, занижая тем самым фактическое время выполнения машинных команд.
Да мы можем точно измерять, сколько тактов выполнялся блок из тысячи таких-то команд, но следует с большой осторожностью подходить к оценке времени выполнения одной такой команды. Низкая "разрешающая способность" Учитывая, что пропускная способность большинства инструкций составляет всего один такт, а минимальный промежуток времени, который еше можно измерять, находится в районе пятидесяти-ста тактов, предельная разрешаюшая способность не змулируюших профилировшиков не превышает полста команд. Под "розреюоющей способностью" здесь и далее понимается протяженность "горячей" точки более или менее уверенно распознаваемой профилировшиком. Строго говоря, не эмулирующие профилировщики показывают не саму "горячую" точку, а некоторую протяженную область, к которой эта "горячая" точка принадлежит.
Фундаментальные проблемы профилировки ив большом" )зрофилировкой "в больиюм" мы будем называть измерение времени выполнения структурных единиц програлииы (функций многократно выполняемых циклов и т. д.), а то и всей программы целиком. Профилировке "в большом" присущи свои проблемы. Это и непостоянство времени выполнения, и проблема "второго прохода", и необходимость учета наведенных эффектов... Словом, здесь есть над чем поработать! Непостоянства времени выполнения Если вы профилировали приложения и раныпе, то наверняка сталкивались с тем, что результаты измерений времени выполнения варьируются от прогона к прогону, порой отличаясь один от другого более чем значительно.
Профилировка программ 39 Причин такого непостоянства существует, по меньшей мере, две; 0 программное непостоянство, связанное с тем, что в многозадачных операционных системах (в частности в 1ч)пг)овв) профилируемая программа попадает под влияние чрезвычайно изменчивой окружающей среды; () аппаратное непостоянство, вызванное внутренней "многозадачностью" самого железа.
В силу огромной их значимости для результатов профилировки обе этих причины далее будут рассмотрены во всех подробностях. Программное непостоянство В многозадачной среде, коей и является популярнейшая на сегодняшний лень операционная система чУ)пг)оив, никакая программа не владеет всеми ресурсами системы единолично и вынуждена делить их с остальными задачами. А это значит, что скорость выполнения профилируемой программы непостоянна и находится в тесной зависимости от "окружающей среды".
На практике разброс результатов измерений может достигать 1Π— 15%, а то и больше, особенно, если параллельно с профилировкой исполняются интенсивно нагружающие систему задачи. Тем не менее, особой проблемы в этом нет, — достаточно лишь в каждом сеансе профилировки делать несколько контрольных прогонов и затем нет, не усреднять, а выбирать замер с наименьшим временем выполнения. Дело в том, что измерения производительности — это не совсем обычные инструментальные измерения, и типовые правила метрологии здесь неуместны.