Чтение онлайн

на главную - закладки

Жанры

Ассемблер для процессоров Intel Pentium

Магда Юрий

Шрифт:

cmp EAX, EDX

Следующая команда помещает в регистр ЕАХ содержимое EDX, если число в EDX больше числа в ЕАХ, и оставляет содержимое ЕАХ без изменения, если число в ЕАХ больше числа в EDX:

cmovl EAX, EDX

Наконец, содержимое регистра ЕАХ помещается в регистр ЕВХ. Из этого фрагмента видно, что ветвлений и переходов нет. Перед использованием команды cmov CC необходимо проверить, поддерживается ли она данным типом процессора. Такую проверку можно выполнить с помощью команды cpund.

Рассмотрим еще один пример.

Пусть требуется найти модуль (абсолютное значение) числа. Используя обычную команду условного перехода jge, можно сделать это с помощью следующего программного кода:



Как видно из исходного текста, после команды стр программный код разветвляется. Этого можно легко избежать, если использовать команду cmovl. Более быстродействующий код выглядит так:



В нашем последнем примере представлен окончательный вариант процедуры find num, в которой используются команды set CC и cmovCC (листинг 5.8).

Ранее мы уже достаточно подробно анализировали исходный текст процедуры find num, поэтому остановимся лишь на последних изменениях (они выделены жирным шрифтом). Как видно из листинга, в случае равенства переменных д50 и 1100 команда emove EAX, [ESI] копирует искомое значение в регистр ЕАХ. Следующая инструкция je exit передает управление либо на выход процедуры (флаг ZF = 1), либо следующей команде (в данном случае add ESI, 4). Команда emove EAX, [ESI] не влияет на состояние флагов, поэтому инструкция je exit, фактически, анализирует флаги, установленные командой emp a1, 1100. Как видите, в модифицированном варианте процедуры осталось всего две команды условных переходов.

 

Более-менее сложная программа, помимо условных и безусловных переходов, может содержать один или несколько вычислительных циклов. Вычисления или другие операции, выполняющиеся циклически, могут повторяться от нескольких десятков до сотен миллионов раз, создавая ощутимую нагрузку на память и процессор. Правильная организация циклов помогает не только повысить производительность программы в целом, но и снизить потребление ресурсов. Сейчас мы проанализируем, каким образом можно повысить производительность программы или процедуры на ассемблере за счет оптимизации циклических вычислений.

Листинг 5.8. Поиск элемента массива, находящегося в диапазоне 50-100 (окончательный вариант)



Вначале остановимся на теоретическом аспекте проблемы. В наиболее общем виде цикл представляет собой последовательность команд, начинающихся с определенной метки и возвращающихся на нее после выполнения этой последовательности. В псевдокодах ассемблера цикл можно представить так:



Например, следующая последовательность команд представляет собой простой цикл:



В этом цикле выполняется увеличение содержимого регистра ЕВХ от 0 до 100 000, и при достижении этого значения передается управление на метку exit.

Проанализируем

этот фрагмент кода с точки зрения быстродействия. Его нельзя назвать оптимальным, поскольку для анализа условия выхода из цикла и самого выхода из цикла используется несколько команд переходов. Для цикла с фиксированным числом итераций проблему оптимизации решить несложно, как показано в следующем фрагменте кода:



Как видно из этого листинга, значение счетчика цикла помещается в регистр EDX. Этот фрагмент более эффективен, чем предыдущий. Команда декремента устанавливает флаг ZF, когда счетчик становится равным 0, что приводит к выходу из цикла, иначе цикл продолжается. Этот фрагмент кода требует меньшего количества команд и будет выполняться быстрее.

Еще один способ повышения быстродействия циклических вычислений состоит в том, чтобы по возможности избавиться от ветвлений и условных переходов внутри самого цикла. Рассмотрим пример (листинг 5.9). Пусть в массиве целых чисел необходимо заменить все отрицательные числа нулями. Это можно сделать с помощью 32-разрядной процедуры на ассемблере (назовем ее setO).


Листинг 5.9. Замена отрицательных элементов массива целых чисел нулевыми значениями



В этой процедуре выполняется основной цикл, операторы которого находятся между меткой next и инструкцией jnz next и образуют тело цикла. В теле цикла присутствует команда jge nochange, выполняющая ветвление в зависимости от результата сравнения. Подобные изменения в последовательности выполнения отрицательно сказываются на быстродействии, поэтому попробуем избавиться от лишнего перехода. Сделать это можно с помощью команды setge. Посмотрим, как будет выглядеть модифицированный вариант процедуры (листинг 5.10).

Листинг 5.10. Модифицированный вариант листинга 5.9, в котором используется команда setge



Хочу отметить, что даже хорошо оптимизированный цикл иногда не работает так быстро, как ожидает разработчик. Для дальнейшего повышения эффективности прибегают к так называемому разворачиванию (unrolling) цикла. Этот термин означает на самом деле, что цикл должен выполнять больше действий в одной итерации для уменьшения количества итераций. Это дает неплохой эффект, и сейчас мы рассмотрим два фрагмента программного кода, в которых имеет место разворачивание циклов.

В качестве исходного (неоптимизированного) фрагмента кода возьмем, например, копирование данных размером в двойное слово из одного буфера памяти (обозначим его как src) в другой (dst). Исходный текст представлен в листинге 5.11.


Листинг 5.11. Копирование двойных слов без оптимизации



Для разворачивания цикла выполним одновременно копирование двух двойных слов. Исходный текст оптимизированного фрагмента кода показан в листинге 5.12 (изменения выделены жирным шрифтом).

Поделиться:
Популярные книги

Попаданка в академии драконов 2

Свадьбина Любовь
2. Попаданка в академии драконов
Любовные романы:
любовно-фантастические романы
6.95
рейтинг книги
Попаданка в академии драконов 2

Береги честь смолоду

Вяч Павел
1. Порог Хирург
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Береги честь смолоду

Клан

Русич Антон
2. Долгий путь домой
Фантастика:
боевая фантастика
космическая фантастика
5.60
рейтинг книги
Клан

Афганский рубеж

Дорин Михаил
1. Рубеж
Фантастика:
попаданцы
альтернативная история
7.50
рейтинг книги
Афганский рубеж

Физрук: назад в СССР

Гуров Валерий Александрович
1. Физрук
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Физрук: назад в СССР

Огни Аль-Тура. Желанная

Макушева Магда
3. Эйнар
Любовные романы:
любовно-фантастические романы
эро литература
5.25
рейтинг книги
Огни Аль-Тура. Желанная

Кодекс Охотника. Книга III

Винокуров Юрий
3. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
7.00
рейтинг книги
Кодекс Охотника. Книга III

(не)Бальмануг.Дочь

Лашина Полина
7. Мир Десяти
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
(не)Бальмануг.Дочь

Внешняя Зона

Жгулёв Пётр Николаевич
8. Real-Rpg
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Внешняя Зона

Измена. Верни мне мою жизнь

Томченко Анна
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Измена. Верни мне мою жизнь

Везунчик. Проводник

Бубела Олег Николаевич
3. Везунчик
Фантастика:
фэнтези
6.62
рейтинг книги
Везунчик. Проводник

Особое назначение

Тесленок Кирилл Геннадьевич
2. Гарем вне закона
Фантастика:
фэнтези
6.89
рейтинг книги
Особое назначение

Вперед в прошлое 2

Ратманов Денис
2. Вперед в прошлое
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Вперед в прошлое 2

Проклятый Лекарь IV

Скабер Артемий
4. Каратель
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Проклятый Лекарь IV