【发布时间】:2014-12-09 19:58:00
【问题描述】:
我试图了解使用 SSE 指令进行矢量化的工作原理。
这里是实现矢量化的代码 sn-p:
#include <stdlib.h>
#include <stdio.h>
#define SIZE 10000
void test1(double * restrict a, double * restrict b)
{
int i;
double *x = __builtin_assume_aligned(a, 16);
double *y = __builtin_assume_aligned(b, 16);
for (i = 0; i < SIZE; i++)
{
x[i] += y[i];
}
}
还有我的编译命令:
gcc -std=c99 -c example1.c -O3 -S -o example1.s
这里是汇编代码的输出:
.file "example1.c"
.text
.p2align 4,,15
.globl test1
.type test1, @function
test1:
.LFB7:
.cfi_startproc
xorl %eax, %eax
.p2align 4,,10
.p2align 3
.L3:
movapd (%rdi,%rax), %xmm0
addpd (%rsi,%rax), %xmm0
movapd %xmm0, (%rdi,%rax)
addq $16, %rax
cmpq $80000, %rax
jne .L3
rep ret
.cfi_endproc
.LFE7:
.size test1, .-test1
.ident "GCC: (Debian 4.8.2-16) 4.8.2"
.section .note.GNU-stack,"",@progbits
我多年前练习过Assembler,我想知道上面代表什么 寄存器 %rdi、%rax 和 %rsi。
我知道 %xmm0 是 SIMD 寄存器,我们可以在其中存储 2 个双精度数据(16 个字节)。
但我不明白如何同时添加:
我认为一切都发生在这里:
movapd (%rdi,%rax), %xmm0
addpd (%rsi,%rax), %xmm0
movapd %xmm0, (%rdi,%rax)
addq $16, %rax
cmpq $80000, %rax
jne .L3
rep ret
%rax 代表“x”数组吗?
%rsi 在 C 代码 sn-p 中代表什么?
最后的结果(比如a[0]=a[0]+b[0]是否存入%rdi?
感谢您的帮助
【问题讨论】:
-
您正在生成 64 位代码,而 rXX 寄存器只是普通 x86 寄存器的 64 位版本(例如 eax = 32 位,rax = 64 位)。
-
使用
-fverbose-asm让 gcc 在每条指令上放置 cmets,为每个操作数命名。 (通常它们只是编号的 tmp 名称,但有时您会得到一个有意义的 C 变量名称。特别是对于数组索引。)
标签: c assembly x86 vectorization auto-vectorization