Подтвердить что ты не робот

Самый эффективный способ установки Register на 1 или (-1)

Сейчас я собираю курс сборки, и парень, который проверяет наши домашние задания, является очень педантичным уловкой оптимизации старой школы. Например, он вычитает 10%, если видит:

mov ax, 0

вместо:

xor ax,ax

даже если он используется только один раз.

Я не полный новичок в программировании сборки, но я не эксперт по оптимизации, поэтому мне нужна ваша помощь во что-то (может быть, очень глупый вопрос, но я все равно спрошу): если мне нужно установить значение регистра 1 или (-1), то лучше использовать:

mov ax, 1

или сделать что-то вроде:

xor ax,ax
inc ax

Мне действительно нужен хороший класс, поэтому я стараюсь сделать его максимально оптимизированным. (Мне нужно оптимизировать время и размер кода)

4b9b3361

Ответ 1

Быстрый google для 8086 instructions timings size появился http://8086.tk/, который, похоже, имеет все тайминги и размеры для 8086 (и более) наборы инструкций.

Без сомнения, вы могли бы найти официальную Intel doco в Интернете с аналогичной информацией.

По вашему конкретному вопросу:

xor ax,ax
inc ax

принимает 3 + 3 = 6 тактов и 2 + 1 = 3 байта, а

mov ax,1

принимает 4 тактовых цикла и 3 байта.

Таким образом, последнее лучше в этом случае.


Но вам нужно поговорить с вашим учебным заведением об этом парне. 10% за простую вещь, такую, как убеждение нищих.

Вы должны спросить, что должно быть сделано в случае, когда у вас есть две возможности: одна быстрее и короче.

Затем, как только они признали, что существуют разные способы кодирования в зависимости от того, что вы пытаетесь достичь, скажите им, что то, что вы пытаетесь достичь, - это читаемость и ремонтопригодность, и серьезно не может дать летящий прыжок о потерянном цикле или байте здесь или там * a.

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

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

* a) Нет, не очень, но иногда бывает полезно выпустить: -)

Ответ 2

Вам лучше с

mov AX, 1

на 8086. Если вы отслеживаете содержимое регистра, вы можете сделать лучше, если знаете, что, например, BX уже имеет в нем 1:

mov AX, BX

или если вы знаете, что AH равно 0:

mov AL, 1

и др.

Ответ 3

В зависимости от ваших обстоятельств вы можете уйти с...

 sbb ax, ax

Результат будет либо 0, если флаг переноса не установлен, либо -1, если установлен флаг переноса.

Однако, если приведенный выше пример не применим к вашей ситуации, я бы рекомендовал

xor  ax, ax
inc  ax

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

Надеюсь, что это поможет.

Ответ 4

Я бы использовал mov [e]ax, 1 при любых обстоятельствах. Его кодировка не больше, чем последовательность хакеров xor, и я уверен, что она быстрее где угодно. 8086 достаточно странно, чтобы быть исключением, и поскольку эта вещь настолько медленная, такая микро-оптимизация будет иметь наибольшее значение. Но где угодно: выполнение 2 "простых" инструкций всегда будет медленнее, чем выполнение 1, особенно если вы рассматриваете опасность данных и длинные конвейеры. Вы пытаетесь прочитать регистр в следующей инструкции после его изменения, поэтому, если ваш процессор не сможет обойти результат со стадии N конвейера (где выполняется xor), чтобы выполнить этап N-1 (где inc пытается загрузить регистр, не говоря уже о добавлении 1 к его значению), у вас будут киоски.

Другие вещи, которые следует учитывать: пропускная способность выборки команд (спор для 16-битного кода, оба они 3 байта); mov избегает изменения флагов (более вероятно, будет полезно, чем принуждение всех их к нулю); в зависимости от того, какие значения могут иметь другие регистры, вы могли бы сделать lea ax,[bx+1] (также 3 байта, даже в 32-битном коде, не влияя на флаги); как говорили другие, sbb ax,ax может работать и в обстоятельствах - он также короче на 2 байта.

Когда вы сталкиваетесь с подобными микро-оптимизациями, вы действительно должны измерять альтернативы, а не слепо полагаться даже на руководства по процессорам.

P.S. Новая домашняя работа: xor bx,bx быстрее, чем xor bx,cx (на любом процессоре)?