Есть ли список устаревших инструкций x86?

Я беру класс программирования на ассемблере x86 и знаю, что определенные инструкции больше использовать не следует - потому что они медленны на современных процессорах; например, инструкция цикла.

Мне не удалось найти ни одного списка инструкций, которые считаются устаревшими и которых следует избегать; любое руководство будет оценено.


person LucidDefender    schedule 02.02.2011    source источник
comment
В основном все сложные инструкции медленнее простых. Хотя технически x86 является CISC, его быстрее использовать как RISC.   -  person ruslik    schedule 03.02.2011
comment
@ruslik: Это не обязательно правда. Если у вас есть сложная инструкция, которая выполняет те же функции, что и набор простых инструкций, вы, вероятно, получите лучшую производительность с помощью специальной инструкции. Скорее всего, он будет оптимизирован и может даже иметь специальное оборудование, которое вы упускаете, используя только простые инструкции.   -  person Nathan Fellman    schedule 03.02.2011
comment
@Nathan Fellman, в связи с этим на ум приходят такие случаи, как _1 _ / _ 2_ инструкции. Однако я не могу вспомнить ни одного случая, когда сложные инструкции были бы быстрее простых. Не могли бы вы назвать для меня несколько, чтобы я был лучше информирован?   -  person mrduclaw    schedule 03.02.2011
comment
Вы не найдете списка, поскольку они действительно никогда не устаревают ... Только те, которые вы используете для данной ситуации, будут меняться в зависимости от архитектуры процессора. Кроме того, некоторые из них недоступны при определенных обстоятельствах, но они все еще не устарели ...   -  person Brian Knoblauch    schedule 02.06.2011


Ответы (4)


Лучше всего обратиться к Официальное руководство Intel по оптимизации.

Это и другие руководства можно найти в здесь.

person Nathan Fellman    schedule 03.02.2011
comment
Это именно тот документ, который я искал! Спасибо. - person LucidDefender; 04.02.2011
comment
См. Также вики-страницу по тегам x86 для ссылок на ресурсы по оптимизации, в частности. Отличные руководства и insn-таблицы Агнера Фога. - person Peter Cordes; 04.03.2016

О, но все же может быть веская причина использовать инструкцию loop. Например, loop label требуется всего два байта. В отличие от dec cx, за которым следует jnz label, требуется три байта. Иногда размер кода важнее скорости.

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

person Jim Mischel    schedule 02.02.2011
comment
dec cx или dec rcx может потребоваться больше байтов в 32- или 64-битном режиме - person phuclv; 26.04.2014
comment
Для новичков в asm, минимизация количества инструкций и особенно. количество ветвей, является разумным приближением для эффективности. Я часто вижу вопросы начинающих с огромным количеством ветвлений (например, сравнение и ветвление, затем безусловное ветвление в другое место или даже jmp label / label:, чтобы перепрыгнуть через пустую строку между блоками ...). Думаю, думать о ветвях как о том, что они проваливаются или нет, требует практики. Совершенно верно, что пытаться написать код, который бы избегал ловушек для ряда процессоров AMD и Intel, сложно. Но см. agner.org/optimize для таблиц insn и записей uarch. - person Peter Cordes; 04.03.2016

Все инструкции ЦП на 100% функциональны для достижения совместимости со старыми ЦП. Так почему бы избежать некоторых инструкций? Нет действительно устаревших инструкций x86! Но мы можем сказать:

1) Все операции со строками, такие как rep movsb, выполняются медленнее.

2) xlat работает медленно и очень редко используется.

3) Также медленно используются функции кадра стека ENTER и LEAVE.

4) В Windows (XP, Vista ...) устаревшие инструкции - IN и OUT, но только в кольце ЦП 2 (уровень приложения), а также int nn не рекомендуется, за исключением int3 (ловушка отладчика ).

РЕДАКТИРОВАТЬ: добавлен простой тест скорости для проверки строковых инструкций rep cmp на разных версиях ЦП.

Тестирование выполняется в среде IDE Delphi, но часть asm очень легко перевести в любую другую среду IDE.

program ProjectTest;

{$APPTYPE CONSOLE}

uses SysUtils, windows;

const
  ArraySize = 50000;

var
  StartTicks    :int64;
  EndTicks      :int64;
  arA           :array [0..ArraySize - 1]of byte;
  arB           :array [0..ArraySize - 1]of byte;

begin
  FillChar(ArA, SizeOf(ArA), 255);          //Set all bytes to 0xFF
  FillChar(ArB, SizeOf(ArB), 255);          //Set all bytes to 0xFF

repeat
  Sleep(100);       //Calm down
  asm
//Save  StartTicks
    rdtsc
    mov         dword ptr [StartTicks], eax
    mov         dword ptr [StartTicks + 4], edx
//Test LOOP
    push        edi
    mov         ecx, -ArraySize
    mov         edi, offset arA + ArraySize
    mov         esi, offset arB + ArraySize
@loop:
    mov         al,[esi + ecx]
    cmp         [edi + ecx], al
    jnz         @exit
    inc         ecx
    jnz         @loop
@exit:
    pop         edi
//Save  EndTicks
    rdtsc
    mov         dword ptr [EndTicks], eax
    mov         dword ptr [EndTicks + 4], edx
  end;

  WriteLn('Loop ticks : ' + IntToStr(EndTicks - StartTicks));

  Sleep(100);       //Calm down
  asm
//Save  StartTicks
    rdtsc
    mov         dword ptr [StartTicks], eax
    mov         dword ptr [StartTicks + 4], edx
//Test REP
    push        edi
    cld
    mov         ecx, ArraySize
    mov         edi, offset arA
    mov         esi, offset arB
    repe        cmpsb
    pop         edi
//Save  EndTicks
    rdtsc
    mov         dword ptr [EndTicks], eax
    mov         dword ptr [EndTicks + 4], edx
  end;

  WriteLn('Rep ticks  : ' + IntToStr(EndTicks - StartTicks));

  ReadLn                    //Wait keyboard
until false;

end.

ТЕСТЫ для ArraySize = 50000

Средние результаты ...

1) Результаты моего одноядерного процессора Intel Pentium 4: тики цикла: 232000; Количество тиков: 233000

2) Результаты моего процессора Intel Core 2 Quad: тики цикла: 158000; Количество тиков: 375000

person GJ.    schedule 03.02.2011
comment
Эти детали, мягко говоря, очень зависят от ЦП. То, что вы пишете, очень верно для одних процессоров и совершенно неверно для других. - person Nathan Fellman; 03.02.2011
comment
Согласен ... Эти данные действительны для новых процессоров Intel со встроенной технологией Hyper-threading. - person GJ.; 03.02.2011
comment
@GJ, вы упомянули, что все операции со строками [sic] медленнее. Медленнее чего? Кроме того, уверены ли вы, что все инструкции стиля int nn устарели, кроме int 3? Как насчет int 1, пошагового прерывания? - person mrduclaw; 03.02.2011
comment
@mrduclaw, int 1 под IA32? :) Первые 32 номера вектора прерывания зарезервированы Intel для использования системой, поэтому система может их использовать! По скорости строковых инструкций ниже, чем у кода без строковых инструкций и той же функции. - person GJ.; 03.02.2011
comment
@GJ, да int 1 под IA32. Я думаю, вы путаете связь между зарезервированным для системного использования и устаревшим? Я не знаю никаких отладчиков, которые не позволяют выполнять пошаговый код; так что вряд ли он устарел. Но что касается строковых инструкций, не могли бы вы дать мне серию инструкций по сборке, для выполнения которых требуется меньшее количество тактовых циклов, чем, скажем, repe cmpsb, чтобы я мог сравнить? - person mrduclaw; 04.02.2011
comment
Я сказал: на самом деле нет устаревших инструкций для x86! Но под некоторыми ОС, такими как win XP, на уровне приложений они существуют. В соответствии с повторением cmpsb я добавил в свой ответ простой тест. - person GJ.; 05.02.2011
comment
rep stos / rep movs работают быстро на процессорах Intel. Для memset / memcpy размером более ~ 128 Б они могут превзойти любой цикл SSE или AVX при использовании с выровненными входами. Это особенно верно для IvyBridge и более поздних версий с функцией ERMSB (которая делает rep stosb лучшим выбором, а не rep stosq и затем очистку). repe / repne инструкции сравнения / поиска не очень быстрые, и вы можете справиться с ними с помощью хорошего SSE pcmpeqb loop. - person Peter Cordes; 04.03.2016
comment
В руководстве по оптимизации Intel есть глава, посвященная memset / memcpy, с графиками их оптимизированной реализации SSE (из их высокопроизводительной библиотеки) в сравнении с rep movs для различных размеров и выравнивания. Не смешивайте rep movs с repe cmps. rep movs может использовать хранилища, которые избегают накладных расходов на чтение для владения при промахах в кеше, но без удаления записанных данных из кеша. (При использовании SSE вы должны выбирать обычные хранилища (хуже для больших буферов) и movnt хранилищ (гораздо хуже для небольших буферов, так как они вытесняют записанные строки из кеша).) - person Peter Cordes; 04.03.2016
comment
Кроме того, enter работает медленно, и его следует избегать. leave неплохо. Агнер Фог указывает, что это 3 мупа для Intel, но IDK, если он включает синхронизацию стекового движка. Если это так, то это так же быстро, как mov rsp, rbp / pop rbp, иначе на 1 мк хуже, но при этом размер кода сохраняется. gcc использует его (обычно только в функциях с массивами переменной длины C99, где громоздко добавлять нужное количество в rsp, чтобы восстановить rsp таким образом.) И, конечно, со значением по умолчанию -fomit-frame-pointer, gcc обычно создает только кадры стека в функциях с массивами переменной длины. Clang вообще его не использует. - person Peter Cordes; 04.03.2016

Если вам что нужно знать, чего следует избегать, обратитесь непосредственно к производителям процессоров, и Intel, и AMD имеют руководства для инструкций, устанавливают поддержку их процессоров и в какой степени они их поддерживают, ваш лучший выбор, если, вероятно, объемы оптимизации, но если ваш единственный только начинаете, прислушайтесь к совету Джима, сначала получите работу, прежде чем беспокоиться о скорости

person Necrolis    schedule 03.02.2011