汇编——SSE对齐

本文详细介绍了SIMD(SingleInstrumentMultiData)架构,以及MMX和SSE(StreamingSIMDExtension)的发展与扩展。重点讨论了未对齐内存下SSE的处理方式,以及与对齐内存时的差异,如movups和addps指令在不同情况下的使用。
摘要由CSDN通过智能技术生成

SIMD是(Single Instrument Multi Data),MMX实现了SIMD;SSE是(Streaming SIMD Extension),它取代了MMX;后来AVX(Advanced Vector Extension,高级向量扩展)对SSE进行了扩展。

未对齐的情况

如下代码展示了SSE处理未对齐内存的情况:

; sse_unaligned.asm
extern printf
section .data
    spvector1   dd  1.1
                dd  2.2
                dd  3.3
                dd  4.4
    spvector2   dd  1.1
                dd  2.2
                dd  2.2
                dd  3.3
    dpvector1   dq  1.1
                dq  2.2
    dpvector2   dq  3.3
                dq  4.4
    fmt1        db  "Single Precision Vector 1: %f, %f, %f, %f", 10, 0
    fmt2        db  "Single Precision Vector 2: %f, %f, %f, %f", 10, 0
    fmt3        db  "Sum of Single Precision Vector 1 and Vector 2: %f, %f, %f %f", 10, 0
    fmt4        db  "Doule Precision Vector 1: %f, %f", 10, 0
    fmt5        db  "Doule Precision Vector 2: %f, %f", 10, 0
    fmt6        db  "Sum of Double Precision Vector 1 and Vector 2: %f, %f", 10, 0

section .bss
    spvector_res resd 4
    dpvector_res resq 4
section .text
    global main
main:
push rbp
mov rbp, rsp
    mov     rsi, spvector1
    mov     rdi, fmt1
    call    printspfp

    mov     rsi, spvector2
    mov     rdi, fmt2
    call    printspfp

    movups  xmm0, [spvector1]
    movups  xmm1, [spvector2]
    addps   xmm0, xmm1
    movups  [spvector_res], xmm0
    mov     rsi, spvector_res
    mov     rdi, fmt3
    call    printspfp

    mov     rsi, dpvector1
    mov     rdi, fmt4
    call    printdpfp

    mov     rsi, dpvector2
    mov     rdi, fmt5
    call    printdpfp

    movupd  xmm0, [dpvector1]
    movupd  xmm1, [dpvector2]
    addpd   xmm0, xmm1
    movupd  [dpvector_res], xmm0
    mov     rsi, dpvector_res
    mov     rdi, fmt6
    call    printdpfp
leave
ret

printspfp:
push rbp
mov rbp, rsp
    movss       xmm0, [rsi]
    cvtss2sd    xmm0, xmm0
    movss       xmm1, [rsi+4]
    cvtss2sd    xmm1, xmm1
    movss       xmm2, [rsi+8]
    cvtss2sd    xmm2, xmm2
    movss       xmm3, [rsi+12]
    cvtss2sd    xmm3, xmm3
    mov         rax, 4
    call        printf
leave
ret

printdpfp:
push rbp
mov rbp, rsp
    movsd   xmm0, [rsi]
    movsd   xmm1, [rsi+8]
    mov     rax, 2
    call    printf
leave
ret

需要注意的几个指令如下:
movups: 移动未对齐的打包单精度;(u:未对齐unalignedp:打包的packeds:单精度single;)
addps: 打包单精度相加;
movss: 移动标量单精度;(s:标量scalars:单精度single
cvtss2sd: 将标量单精度转换为标量双精度;(d:双精度double

对齐的情况

; sse_aligned.asm
extern printf
section .data
    dummy       db      13
align 16
    spvector1   dd      1.1
                dd      2.2
                dd      3.3
                dd      4.4
    spvector2   dd      1.1
                dd      2.2
                dd      3.3
                dd      4.4
    dpvector1   dq      1.1
                dq      2.2
    dpvector2   dq      3.3
                dq      4.4

    fmt1        db      "Single Precision Vector 1: %f, %f, %f, %f", 10, 0
    fmt2        db      "Single Precision Vector 2: %f, %f, %f, %f", 10, 0
    fmt3        db      "Sum of Single Precision Vector 1 and Vector 2: %f, %f, %f %f", 10, 0
    fmt4        db      "Doule Precision Vector 1: %f, %f", 10, 0
    fmt5        db      "Doule Precision Vector 2: %f, %f", 10, 0
    fmt6        db      "Sum of Double Precision Vector 1 and Vector 2: %f, %f", 10, 0

section .bss
alignb  16
    spvector_res resd 4
    dpvector_res resq 4
section .text
    global main
main:
push rbp
mov rbp, rsp
    mov     rsi, spvector1
    mov     rdi, fmt1
    call    printspfp

    mov     rsi, spvector2
    mov     rdi, fmt2
    call    printspfp

    movaps  xmm0, [spvector1]
    addps   xmm0, [spvector2]

    movaps  [spvector_res], xmm0
    mov     rsi, spvector_res
    mov     rdi, fmt3
    call    printspfp

    mov     rsi, dpvector1
    mov     rdi, fmt4
    call    printdpfp

    mov     rsi, dpvector2
    mov     rdi, fmt5
    call    printdpfp

    movapd  xmm0, [dpvector1]
    addpd   xmm0, [dpvector2]

    movapd  [dpvector_res], xmm0
    mov     rsi, dpvector_res
    mov     rdi, fmt6
    call    printdpfp
;leave
mov rsp, rbp
pop rbp
ret

printspfp:
push rbp
mov rbp, rsp
    movss       xmm0, [rsi]
    cvtss2sd    xmm0, xmm0
    movss       xmm1, [rsi+4]
    cvtss2sd    xmm1, xmm1
    movss       xmm2, [rsi+8]
    cvtss2sd    xmm2, xmm2
    movss       xmm3, [rsi+12]
    cvtss2sd    xmm3, xmm3
    mov         rax, 4
    call        printf
leave
ret

printdpfp:
push rbp
mov rbp, rsp
    movsd   xmm0, [rsi]
    movsd   xmm1, [rsi+8]
    mov     rax, 2
    call    printf
leave
ret

需要注意的几点如下:
movaps: 移动未对齐的打包单精度;(a:对齐alignedp:打包的packeds:单精度single;)
对齐的内存不需要像未对齐内存一样,将内存中的数据移动到寄存器xmm中然后再调用addps进行计算,只需要把其中一个移动进寄存器中即可。

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

腾昵猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值