【发布时间】:2014-09-01 03:35:36
【问题描述】:
我有以下代码,这似乎是 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 怎么不使用mulpdaddpd 而不是mulsds 和addsds 这两个?我用-fopt-info-all-vec 试图找出原因,它抱怨对齐(@987654321@):
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: warning: attribute 'aligned' is ignored, place it after "struct" to apply attribute to type declaration [-Wignored-attributes]。 -
这是铿锵警告吗?我的 gcc 似乎不支持它。无论如何,将
__attribute__((aligned(16)))移动到正确的位置似乎并没有改变任何东西。 -
矢量化它没有任何好处。
u和v之后需要单独访问。执行此操作所需的解包开销超过了向量化单个算术运算的好处。 -
嗯...我对矢量化不是很了解,但是您确实只使用一对标量。没有用于打包更多标量的循环
-
@Mysticial
u >= 0.0 && v >= 0.0比较也应该是可矢量化的,因此仅对并不总是执行的u + v <= 1.0比较需要解包。
标签: c gcc vectorization