- •1.Способи адресації
- •3.Пряма адресація пам'яті. .
- •6. Сторінкова пам'ять.
- •7.Сегмента адресація.
- •8. Опосередкована адресація з масштабуванням
- •9.Адресація по базі з сувом.
- •10.Адресація по базі з індексуванням
- •11. Адресація по базі з індексуванням та масштабуванням
- •12.Вирівнювання даних та коду.
- •13. Регістри загального призначення
- •14. Сегментні регістри.
- •15.Індексні регістри.
- •16. Спеціальні регістри
- •17. Флаги ознак.
- •18. Регистры управления (Control Registers)
- •19.20. Стек, регітсри стека.
- •22. Флаг нуля zf
- •23. Флаг знака sf
- •25. Флаг четности.
- •26. Флаг полупереносу.
- •27. Флаг трассировки.
- •28. Флаг напрямку.
- •29. Флаг переривание.
- •35. Арифметические команды
- •36. Команди блочної обробки даних
- •37. Команды ввода и вывода
- •38. Команды управления флагами
- •39. Команда пересылки данных: возможности и ограничения
- •40. Команди керування
- •41. Стек математичного співпроцесора
- •42.Команди пересилки співпроцесора
- •43. Арифметические команды сопроцессора
- •46. Різновиди чисел
- •47. Способи округлення
- •48.Трансцендентні команди
- •49. Команди завантаження констант співпроцесора
- •50. Порівняння чисел з плаваючою комою
- •51. Структура жёсткого диска
- •58. Структура каталогов Linux
- •59. Структура ufs
- •60. Суперблок. Ufs
- •61. Индексный дескриптор ufs
- •62. Основні механізми передачі параметрів
- •63. Основні місця передачі параметрів
- •64. Вкладені обчислення
- •65. Різновиди комбінацій сегментів
- •66. Порядок завантаження сегментів, директиви
- •67. Оптимізація обчислень
- •68. Математична оптимізація
- •69. Алгоритмічна оптимізація
- •70 .Низькорівнева оптимізація
- •71. Основні методи алгоритмічної оптимізації
- •72. Основні рекомендації низького рівня
- •74. Особенности архитектуры процессоров Pentium Pro и Pentium II
- •76. Конвеєр fpu
- •77. Принципи роботи кешу
- •79. Регистры управления (Control Registers)
- •80. Індексні регістри дескрипторів
- •81. Віртуалізація пам’яті
- •82. Переривання, маскування та обробка.
- •84. Кеш з зворотнім записом
- •85. Кеш з відкладеним записом
- •86. Наскрізний кеш
- •87. Кеш читання
- •88. Повністю асоціативний кеш
- •91. Структура кешу
- •92. Теги, призначення
- •93. Конвеєри mmx та sse
70 .Низькорівнева оптимізація
Включает такие техники, как:
Оптимальный выбор (замена, объединение, разделение) инструкций
Переупорядочивание инструкций
Распределение регистров
Удаление цепочек переходов
Векторизация
Понижение силы операций
Объединение и разделение инструкций
Данный метод оптимизации состоит в замене одной или нескольких инструкций другим, но функционально эквивалентным набором, дающим выигрыш для целевой архитектуры.
Так, для конвейерной архитектуры разделение сложных инструкций на более простые может давать выигрыш в быстродействии, если несколько инструкций могут быть параллельно выполнены на конвейере. Так, например, процессор Pentium MMX быстрее выполнит набор инструкций
dec ecx
jnz метка
чем эквивалентную ему инструкцию loop метка; для ранних процессоров архитектуры x86, от 8086 до 80286, всё иначе, так как они выполняют инструкции неконвейеризированно, вследствие чего команда loop метка создаёт более экономичный и быстрый код для этих процессоров.
Так как процессоры Intel используют весьма сложный набор команд, большинство операций можно выполнить на низком уровне очень многими способами. При этом иногда оказывается, что наиболее очевидный способ — не самый быстрый или короткий. Часто простыми перестановками команд, зная механизм выполнения команд на современных процессорах, реально заставить ту же процедуру выполняться на 50 – 200% быстрее. Разумеется, переходить к этому уровню оптимизации можно только после того, как текст программы окончательно написан и максимально оптимизирован на среднем уровне.
Перечислим основные рекомендации, которым нужно следовать при оптимальном программировании для процессоров Intel Pentium, Pentium MMX, Pentium Pro и Pentium II.
Основные рекомендации
Используйте регистр ЕАХ всюду, где возможно. Команды с непосредственным операндом, с операндом — абсолютным адресом переменной и команды XCHG с регистрами занимают на один байт меньше, если другой операнд — регистр ЕАХ.
Используйте регистр DS всюду, где возможно. Префиксы переопределения сегмента увеличивают размер программы на 1 байт и время на 1 такт.
Если к переменной в памяти, адресуемой со смещением, выполняется несколько обращений — загрузите ее в регистр.
Не используйте сложные команды — ENTER, LEAVE, LOOP, строковые команды, если аналогичное действие можно выполнить небольшой последовательностью простых команд.
Не используйте команду MOVZX для чтения байта — это требует 4 тактов для выполнения. Заменой может служить такая пара команд:
xor еах,еах
mov al,source
Используйте TEST для сравнения с нулем или для других проверок равенства:
test eax,eax
jz if_zero ; переход, если ЕАХ = 0
test eax,source
jz if_zero ; переход, если ЕАХ = source
Исцользуйте команду XOR, чтобы обнулять регистр (конечно, если текущее состояние флагов больше не потребуется), эта команда официально поддерживается Intel как команда обнуления регистра:
xor еах,еах ; ЕАХ = 0
Не используйте умножение или деление на константу — его можно заменить другими командами, например:
; ЕАХ = ЕАХ * 10
shl eax,1 ; умножение на 2
lea eax,[eax+eax*4] ; умножение на 5
; ЕАХ = ЕАХ * 7
mov ebx,eax
shl еах,3 ; умножение на 8
sub eax,ebx ; и вычитание сохраненного ЕАХ
; АХ = АХ/10
mov dx,6554 ; DX = 65 536/10
mul dx ; DX = AX/10 (умножение
; выполняется быстрее деления)
; ЕАХ = ЕАХ mod 64 (остаток от деления на степень двойки)
and eax,3Fh
Используйте короткую форму команды jmp, где возможно (jmp short метка).
Как можно реже загружайте сегментные регистры.
Как можно меньше переключайте задачи — это очень медленная процедура. Часто, если надо сохранять небольшое состояние процесса, например для реализации нитей, переключение быстрее организовать программно.
Команда LEA
LEA можно использовать (кроме прямого назначения — вычисления адреса сложно адресуемой переменной) для следующих двух ситуаций:
быстрое умножение
lea еах,[еах*2] ; ЕАХ = ЕАХ * 2 (shl eax,1
; лучше)
lea еах,[еах+еах*2] ; ЕАХ = ЕАХ * 3
lea еах,[еах*4] ; ЕАХ = ЕАХ * 4 (shl eax,2
; лучше)
lea еах,[еах+еах*4] ; ЕАХ = ЕАХ * 5
lea еах,[еах+еах*8] ; ЕАХ = ЕАХ * 9
трехоперандное сложение
lea ecx,[eax+ebx] ; ЕСХ = ЕАХ * ЕВХ
Единственный недостаток LEA — увеличивается вероятность AGI с предыдущей командой (см. ниже).
Выравнивание
Восьмибайтные данные должны быть выравнены по восьмибайтным границам (то есть три младших бита адреса должны быть равны нулю).
Четырехбайтные данные должны быть выравнены по границе двойного слова (то есть два младших бита адреса должны быть равны нулю).
Двухбайтные данные должны полностью содержаться в выравненном двойном слове (то есть два младших бита адреса не должны быть равны единице).
80-битные данные должны быть выравнены по 16-байтным границам.
Когда нарушается выравнивание при доступе к данным, находящимся в кэше, теряются 3 такта на каждое невыравненное обращение на Pentium и 9 – 12 тактов — на Pentium Pro/Pentium II.
Так как линейка кэша кода составляет 32 байта, метки для переходов, особенно метки, отмечающие начало цикла, должны быть выравнены по 16-байтным границам, а массивы данных, равные или большие 32 байт, должны начинаться с адреса, кратного 32.
AGI
AGI — это ситуация, при которой регистр, используемый командой для генерации адреса как базовый или индексный, был приемником предыдущей команды. В этой ситуации процессор тратит один дополнительный такт. Последовательность команд
add edx,4
mov esi,[edx]
выполняется с AGI на любом процессоре.
Последовательность команд
add esi,4 ; U-конвейер - 1 такт (на Pentium)
pop ebx ; V-конвейер - 1 такт
inc ebx ; V-конвейер - 1 такт
mov edi,[esi] ; в U-конвейер - *AGI*, затем 1 такт
выполняется с AGI на Pentium за три такта процессора.
Кроме того, AGI может происходить неявно, например при изменении регистра ESP и обращении к стеку:
sub esp,24
push ebx ; *AGI*
или
mov esp,ebp
pop ebp ; *AGI*
но изменение ESP, производимое командами PUSH и POP, не приводит к AGI, если следующая команда тоже обращается к стеку.
Процессоры Pentium Pro и Pentium II не подвержены AGI.
Обращение к частичному регистру
Если команда обращается к 32-битному регистру, например ЕАХ, сразу после команды, выполнявшей запись в соответствующий частичный регистр (АХ, AL, АН), происходит пауза минимум в 7 тактов на Pentium Pro и Pentium II и в 1 такт — на 80486, но не на Pentium:
mov ax,8
add ecx,eax ; пауза
На Pentium Pro и Pentium II эта пауза не появляется, если сразу перед командой записи в АХ была команда XOR ЕАХ,ЕАХ или SUB ЕАХ,ЕАХ.
Префиксы
Префиксы LOCK, переопределения сегмента и изменения адреса операнда увеличивают время выполнения команды на 1 такт.