我在试着找出什么是最好的(也许是avx?)此代码的优化
typedef struct {
float x;
float y;
} vector;
vector add(vector u, vector v){
return (vector){u.x+v.x, u.y+v.y};
}运行gcc -S code.c会产生相当长的汇编代码
.file "code.c"
.text
.globl add
.type add, @function
add:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movq %rdi, -8(%rbp)
movss 16(%rbp), %xmm1
movss 48(%rbp), %xmm0
addss %xmm0, %xmm1
movss 32(%rbp), %xmm2
movss 64(%rbp), %xmm0
addss %xmm2, %xmm0
movq -8(%rbp), %rax
movss %xmm1, (%rax)
movq -8(%rbp), %rax
movss %xmm0, 16(%rax)
movq -8(%rbp), %rax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size add, .-add
.ident "GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609"
.section .note.GNU-stack,"",@progbits而对于这么简单的任务,我只期望很少的指令。有没有人可以帮我优化这类代码,同时保持浮点类型?
谢谢。
发布于 2016-11-16 18:42:16
在使用Vector Instructions through Built-in Functions时,gcc可以生成更好的代码
typedef float v2f __attribute__((vector_size(8)));
v2f add(v2f u, v2f v) {
return u + v;
}产生:
add(float __vector(2), float __vector(2)):
movlps %xmm0, -32(%rsp)
movlps %xmm1, -40(%rsp)
movss -32(%rsp), %xmm0
addss -40(%rsp), %xmm0
movss %xmm0, -56(%rsp)
movss -28(%rsp), %xmm0
addss -36(%rsp), %xmm0
movss %xmm0, -52(%rsp)
movlps -56(%rsp), %xmm0
ret这仍然是无效的,因为它执行逐个元素的加法。
xmm registers are 128-bit wide,因此要充分利用它们,代码需要在128位单元上操作。
在3D图形中,坐标通常是4元素浮点向量,这使得{x, y, z, w}寄存器非常适合。例如:
typedef float v4f __attribute__((vector_size(16)));
v4f add(v4f u, v4f v) {
return u + v;
}这将为函数add生成以下程序集
add(float __vector(4), float __vector(4)):
addps %xmm1, %xmm0
rethttps://stackoverflow.com/questions/40628195
复制相似问题