ia32/ia64 上的 ADC 和 ADCX 指令有什么区别?
What is the difference between the ADC and ADCX instructions on ia32/ia64?
当我遇到 ADCX
指令时,我正在翻阅英特尔软件开发人员手册,这是我以前不知道的;它的编码是66 0F 38 F6
。它似乎与 ADC
指令几乎相同,那么为什么在以下情况下使用 ADCX
:
- 它仅在现代 CPU 中受支持
- 指令编码需要更多 space(4 个字节对
ADC
1 个字节)
是否有其他副作用或特殊情况,其中 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
指令有两个消息变体:adcx
和adox
adcx
和adc
一样,只是不再修改OF(溢出)标志。
adox
和adc
一样,只是在OF标志中存放了进位信息。它也不再修改进位标志。
如您所见,两个新的 adc
变体在标志使用方面不会相互影响。这允许您通过交错指令并行地 运行 两个长整数加法,并对一个序列使用 adcx
,对另一个序列使用 adox
。
当我遇到 ADCX
指令时,我正在翻阅英特尔软件开发人员手册,这是我以前不知道的;它的编码是66 0F 38 F6
。它似乎与 ADC
指令几乎相同,那么为什么在以下情况下使用 ADCX
:
- 它仅在现代 CPU 中受支持
- 指令编码需要更多 space(4 个字节对
ADC
1 个字节)
是否有其他副作用或特殊情况,其中 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
指令有两个消息变体:adcx
和adox
adcx
和adc
一样,只是不再修改OF(溢出)标志。
adox
和adc
一样,只是在OF标志中存放了进位信息。它也不再修改进位标志。
如您所见,两个新的 adc
变体在标志使用方面不会相互影响。这允许您通过交错指令并行地 运行 两个长整数加法,并对一个序列使用 adcx
,对另一个序列使用 adox
。