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

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

Жанры

Ассемблер для процессоров 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 (изменения выделены жирным шрифтом).

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

Японская война 1904. Книга третья

Емельянов Антон Дмитриевич
3. Второй Сибирский
Фантастика:
попаданцы
альтернативная история
фэнтези
5.00
рейтинг книги
Японская война 1904. Книга третья

Хозяин Теней 2

Петров Максим Николаевич
2. Безбожник
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Хозяин Теней 2

Телохранитель Генсека. Том 4

Алмазный Петр
4. Медведев
Фантастика:
попаданцы
альтернативная история
6.00
рейтинг книги
Телохранитель Генсека. Том 4

Маленькие Песцовые радости

Видум Инди
5. Под знаком Песца
Фантастика:
альтернативная история
аниме
6.80
рейтинг книги
Маленькие Песцовые радости

Запечатанный во тьме. Том 1. Тысячи лет кача

NikL
1. Хроники Арнея
Фантастика:
уся
эпическая фантастика
фэнтези
5.00
рейтинг книги
Запечатанный во тьме. Том 1. Тысячи лет кача

Командор космического флота

Борчанинов Геннадий
3. Звезды на погонах
Фантастика:
боевая фантастика
космическая фантастика
космоопера
5.00
рейтинг книги
Командор космического флота

Седьмой Рубеж V

Бор Жорж
5. 5000 лет темноты
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Седьмой Рубеж V

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

Винокуров Юрий
1. Кодекс Охотника
Фантастика:
фэнтези
юмористическое фэнтези
попаданцы
боевая фантастика
5.00
рейтинг книги
Кодекс Охотника

Гримуар темного лорда VII

Грехов Тимофей
7. Гримуар темного лорда
Фантастика:
боевая фантастика
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Гримуар темного лорда VII

Третий Генерал: Том VII

Зот Бакалавр
6. Третий Генерал
Фантастика:
городское фэнтези
аниме
сказочная фантастика
попаданцы
5.00
рейтинг книги
Третий Генерал: Том VII

Солнечный флот

Вайс Александр
4. Фронтир
Фантастика:
боевая фантастика
космическая фантастика
5.00
рейтинг книги
Солнечный флот

Виконт. Книга 4. Колонист

Юллем Евгений
Псевдоним `Испанец`
Фантастика:
фэнтези
попаданцы
аниме
7.50
рейтинг книги
Виконт. Книга 4. Колонист

Обреченное королевство

Сандерсон Брендон
1. The Stormlight Archive
Фантастика:
фэнтези
9.30
рейтинг книги
Обреченное королевство

Третий. Том 5

INDIGO
5. Отпуск
Фантастика:
космическая фантастика
фантастика: прочее
5.00
рейтинг книги
Третий. Том 5