我有下面的代码,看起来很适合使用SLP:
除非我对
struct vector {
double x, y, z;
} __attribute__((aligned(16)));
int
slp_test(struct vector *x0, struct vector *n)
{
double t = -x0->z/n->z;
double u = x0->x + t*n->x;
double v = x0->y + t*n->y;
return t >= 0.0 && u >= 0.0 && v >= 0.0 && u + v <= 1.0;
}
u
和v
的计算似乎很容易向量化,x0
和n
也应该足够对齐。但是在x86-64上,使用-O3
编译选项,gcc 4.9.0生成了以下代码:
movsd .LC0(%rip), %xmm1
movsd 16(%rdi), %xmm0
movsd (%rdi), %xmm2
xorpd %xmm1, %xmm0
movsd (%rsi), %xmm1
pxor %xmm3, %xmm3
divsd 16(%rsi), %xmm0 ; t = x0->z/n->z
mulsd %xmm0, %xmm1 ; t*n->x
addsd %xmm1, %xmm2 ; u = x0->x + t*n->x
movsd 8(%rsi), %xmm1
mulsd %xmm0, %xmm1 ; t*n->y
ucomisd %xmm3, %xmm2
addsd 8(%rdi), %xmm1 ; v = x0->y + t*n->y
setae %dl
ucomisd %xmm3, %xmm1
setae %al
testb %al, %dl
je .L3
ucomisd %xmm3, %xmm0
jb .L3
addsd %xmm2, %xmm1
movsd .LC2(%rip), %xmm0
xorl %eax, %eax
ucomisd %xmm1, %xmm0
setae %al
ret
.L3:
xorl %eax, %eax
ret
为什么gcc没有使用mulpd
addpd
来替代两个mulsd
和addsd
呢?我使用-fopt-info-all-vec
尝试查看原因,但它抱怨了对齐问题(完整输出):
slp-test.c:8:17: note: === vect_analyze_data_refs_alignment ===
slp-test.c:8:17: note: vect_compute_data_ref_alignment:
slp-test.c:8:17: note: misalign = 0 bytes of ref x0_3(D)->z
slp-test.c:8:17: note: vect_compute_data_ref_alignment:
slp-test.c:8:17: note: misalign = 0 bytes of ref n_6(D)->z
slp-test.c:8:17: note: vect_compute_data_ref_alignment:
slp-test.c:8:17: note: misalign = 0 bytes of ref x0_3(D)->x
slp-test.c:8:17: note: vect_compute_data_ref_alignment:
slp-test.c:8:17: note: misalign = 0 bytes of ref n_6(D)->x
slp-test.c:8:17: note: vect_compute_data_ref_alignment:
slp-test.c:8:17: note: misalign = 8 bytes of ref x0_3(D)->y
slp-test.c:8:17: note: vect_compute_data_ref_alignment:
slp-test.c:8:17: note: misalign = 8 bytes of ref n_6(D)->y
slp-test.c:8:17: note: === vect_analyze_slp ===
slp-test.c:8:17: note: Failed to SLP the basic block.
slp-test.c:8:17: note: not vectorized: failed to find SLP opportunities in basic block.
除非我对
__attribute__((aligned(16)))
的理解有误,否则它应该能够强制对这些访问进行对齐。你有什么想法吗?
test.c:1:16: 警告:属性'aligned'被忽略,将它放在"struct"之后以将属性应用于类型声明[-Wignored-attributes]
。 - Joachim Isaksson__attribute__((aligned(16)))
移动到正确的位置似乎并没有改变任何东西。 - Tavian Barnesu
和v
。为此需要进行解包的开销超过了向量化单个算术操作的好处。 - Mysticial