ia32/ia64 上的 ADC 和 ADCX 指令有什么区别?

What is the difference between the ADC and ADCX instructions on ia32/ia64?

当我遇到 ADCX 指令时,我正在翻阅英特尔软件开发人员手册,这是我以前不知道的;它的编码是66 0F 38 F6。它似乎与 ADC 指令几乎相同,那么为什么在以下情况下使用 ADCX

是否有其他副作用或特殊情况,其中 ADCX 证明优于 ADC?一定有一些很好的理由将其添加到指令库中。

引用英特尔论文New Instructions Support Large Integer Arithmetic

The adcx and adox instructions are extensions of the adc instruction, designed to support two separate carry chains. They are defined as:

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

Both instructions compute the sum of src1 and src2 plus a carry-in and generate an output sum dest and a carry-out. The difference between these two instructions is that adcx uses the CF flag for the carry in and carry out (leaving the OF flag unchanged), whereas the adox instruction uses the OF flag for the carry in and carry out (leaving the CF flag unchanged).

The primary advantage of these instructions over adc is that they support two independent carry chains.

这些指令用于加速大整数运算。

在这些指令之前,添加大量数字通常会产生如下所示的代码序列:

  add  
  adc  
  adc  
  adc  
  adc  

这里要注意的重要部分是,如果加法的结果不适合机器字,则进位标志被设置并且 'carried over' 到下一个更高的机器字。所有这些指令都相互依赖,因为它们会考虑之前的加法进位标志并且在执行后生成新的进位标志值。

由于 x86 处理器能够同时执行多条指令,这成为了一个巨大的瓶颈。依赖链只是让处理器无法并行执行任何算术。 (为了在实践中正确,您会发现 add/adc 序列之间存在加载和存储,但性能仍然受到进位依赖性的限制)。

为了改进这一点,英特尔通过重新解释溢出标志添加了第二条进位链。

adc指令有两个消息变体:adcxadox

adcxadc一样,只是不再修改OF(溢出)标志。

adoxadc一样,只是在OF标志中存放了进位信息。它也不再修改进位标志。

如您所见,两个新的 adc 变体在标志使用方面不会相互影响。这允许您通过交错指令并行地 运行 两个长整数加法,并对一个序列使用 adcx,对另一个序列使用 adox