В чем разница между инструкциями ADC и ADCX на ia32/ia64?

Я просмотрел руководство разработчика программного обеспечения Intel, когда столкнулся с инструкцией ADCX, которая была ранее неизвестна мне; его кодировка 66 0F 38 F6. Кажется, он почти идентичен инструкции ADC, так зачем использовать ADCX, когда:

  • поддерживается только в современных процессорах
  • кодировка команд занимает больше места (4 байта против 1 для ADC)

Есть ли какой-нибудь другой побочный эффект, или специальный случай, где ADCX оказывается выгодным над ADC? Должно быть, есть веская причина, почему это было добавлено в репертуар команд.

Ответ 1

Процитировать из статьи Новая инструкция по поддержке большой целочисленной арифметики от Intel:

Команды adcx и adox являются расширениями инструкции adc, предназначен для поддержки двух отдельных несущих цепей. Они определяются как:

adcx dest/src1, src2
adox dest/src1, src2

Обе инструкции вычисляют сумму src1 и src2 плюс перенос и генерируют выходная сумма dest и выполнение. Разница между этими двумя что adcx использует флаг CF для переноса и переноса (оставляя флаг OF без изменений), тогда как инструкция adox использует флаг OF для переноса и выполнения (оставляя флаг CF без изменений).

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

Ответ 2

Эти инструкции используются для ускорения большой целочисленной арифметики.

Прежде чем эти инструкции, добавляющие большие числа, часто приводили к кодовой последовательности, которая выглядела так:

  add  
  adc  
  adc  
  adc  
  adc  

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

Так как процессоры x86 способны выполнять сразу несколько инструкций, это стало огромным узким местом. Цепочка зависимостей просто не позволила процессору выполнить любую из арифметических операций параллельно. (чтобы быть на практике, вы найдете нагрузки и хранилища между последовательностями add/adc, но производительность по-прежнему ограничена зависимостью переноса).

Чтобы улучшить это, Intel добавила вторую цепочку переноса, переинтерпретируя флаг переполнения.

Команда adc получила два варианта новостей: adcx и adox

adcx совпадает с adc, за исключением того, что он больше не изменяет флаг OF (переполнения).

adox совпадает с adc, но сохраняет информацию о переносе в флагом OF. Он также не изменяет флаг переноса.

Как вы можете видеть, два новых варианта adc не влияют друг на друга в отношении использования флага. Это позволяет запускать два длинных целочисленных дополнения параллельно, чередуя инструкции и используя adcx для одной последовательности и adox для другой последовательности.