[Назад] [Далее]

9.3. Низкоуровневая оптимизация

9.3.1. Общие принципы низкоуровневой оптимизации

Так как процессоры Intel используют весьма сложный набор команд, большинство операций можно выполнить на низком уровне очень многими способами. При этом иногда оказывается, что наиболее очевидный способ — не самый быстрый или короткий. Часто простыми перестановками команд, зная механизм выполнения команд на современных процессорах, реально заставить ту же процедуру выполняться на 50 – 200% быстрее. Разумеется, переходить к этому уровню оптимизации можно только после того, как текст программы окончательно написан и максимально оптимизирован на среднем уровне.

Перечислим основные рекомендации, которым нужно следовать при оптимальном программировании для процессоров Intel Pentium, Pentium MMX, Pentium Pro и Pentium II.

Основные рекомендации

Команда LEA

LEA можно использовать (кроме прямого назначения — вычисления адреса сложно адресуемой переменной) для следующих двух ситуаций:

Единственный недостаток LEA — увеличивается вероятность AGI с предыдущей командой (см. ниже).

Выравнивание

Когда нарушается выравнивание при доступе к данным, находящимся в кэше, теряются 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 такт.


п»ї
"target=_blank><\/a>") //-->