You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RSQRTSS指令是否会打破对目标寄存器的依赖关系?

问题背景

我使用uiCA工具为以下代码生成了执行跟踪表:

cvtsi2ss xmm0, eax
addss xmm0, xmm0

从结果可以看到,每条cvtsi2ss必须等待上一轮迭代执行完成,原因是该指令依赖xmm0寄存器的32:127位——指令执行时这部分位保持不变,会直接透传到输出结果。

但将cvtsi2ss替换为rsqrtss后,工具给出的执行表现结果出现了很大差异,对应测试代码如下:

rsqrtss xmm0, xmm1
addss xmm0, xmm0

此时uiCA的跟踪结果显示每条rsqrtss都可以和上一轮迭代的指令并行执行。我对此存在疑惑:rsqrtss和cvtsi2ss的行为一致,写入目标寄存器时都会保留32:127位不变,按理应当和cvtsi2ss一样,需要等待目标寄存器上的所有前序操作完成后才能执行,不应该出现并行执行的情况。


实际硬件验证

查阅相关解答后我运行了简单的性能测试,基本可以确认uiCA在该场景下存在模拟bug,同时IACA也未能识别到这一输出依赖。如果测试代码存在问题欢迎指正,测试代码与运行结果如下:

测试代码

__asm__ (
    R"(.section .text
    .balign 16
noXor:
    mov eax, 0x3f800000
    movd xmm1, eax
    rdtscp
    shl rdx, 32
    or rax, rdx
    mov rdi, rax
    mov ecx, 1 << 30
    jmp noXor_loop
    .balign 16
noXor_loop:
    rsqrtss xmm0, xmm1
    addss xmm0, xmm0
    dec ecx
    jnz noXor_loop
    rdtscp
    shl rdx, 32
    or rax, rdx
    sub rax, rdi
    ret
    .balign 16
yesXor:
    mov eax, 0x3f800000
    movd xmm1, eax
    rdtscp
    shl rdx, 32
    or rax, rdx
    mov rdi, rax
    mov ecx, 1 << 30
    jmp yesXor_loop
    .balign 16
yesXor_loop:
    xorps xmm0, xmm0
    rsqrtss xmm0, xmm1
    addss xmm0, xmm0
    dec ecx
    jnz yesXor_loop
    rdtscp
    shl rdx, 32
    or rax, rdx
    sub rax, rdi
    ret)"
);

unsigned long long noXor(void);
unsigned long long yesXor(void);

#include <stdio.h>

int main() {
    for (int i = 0; i < 4; ++i) {
        printf("noXor: %llu yesXor: %llu\n", noXor(), yesXor());
    }
    return 0;
}

运行结果

noXor: 4978836501 yesXor: 696810039
noXor: 4971780086 yesXor: 690780109
noXor: 4977293771 yesXor: 687404710
noXor: 5499602729 yesXor: 687954399

测试结果显示,未提前清零xmm0的noXor版本运行耗时是提前清零版本的7倍左右,证明rsqrtss确实存在对xmm0高位的依赖,会阻塞后续指令执行,uiCA和IACA的静态模拟结果均不符合实际硬件表现。

内容的提问来源于stack exchange,提问作者xiver77

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 01:15:39