gpt4 book ai didi

c - 使用 sse 执行内在函数

转载 作者:太空狗 更新时间:2023-10-29 15:41:23 25 4
gpt4 key购买 nike

我目前正在开始使用 SSE。我之前关于 SSE ( Mutiplying vector by constant using SSE) 的问题的答案让我想到了测试使用像 _mm_mul_ps() 这样的内在函数和只使用“普通运算符”(不确定什么是最好的术语)之间的区别是)像*

所以我写了两个测试用例,它们只是计算结果的方式不同:
方法一:

int main(void){
float4 a, b, c;

a.v = _mm_set_ps(1.0f, 2.0f, 3.0f, 4.0f);
b.v = _mm_set_ps(-1.0f, -2.0f, -3.0f, -4.0f);

printf("method 1\n");
c.v = a.v + b.v; // <---
print_vector(a);
print_vector(b);
printf("1.a) Computed output 1: ");
print_vector(c);

exit(EXIT_SUCCESS);
}

方法二:

int main(void){
float4 a, b, c;

a.v = _mm_set_ps(1.0f, 2.0f, 3.0f, 4.0f);
b.v = _mm_set_ps(-1.0f, -2.0f, -3.0f, -4.0f);

printf("\nmethod 2\n");
c.v = _mm_add_ps(a.v, b.v); // <---
print_vector(a);
print_vector(b);
printf("1.b) Computed output 2: ");
print_vector(c);

exit(EXIT_SUCCESS);
}

两个测试用例共享以下内容:

typedef union float4{
__m128 v;
float x,y,z,w;
} float4;

void print_vector (float4 v){
printf("%f,%f,%f,%f\n", v.x, v.y, v.z, v.w);
}

因此,为了比较我使用以下方法编译的两种情况生成的代码:
gcc -ggdb -msse -c t_vectorExtensions_method1.c

这导致(仅显示两个 vector 相加的部分 - 不同之处):
方法一:

    c.v = a.v + b.v;
a1: 0f 57 c9 xorps %xmm1,%xmm1
a4: 0f 12 4d d0 movlps -0x30(%rbp),%xmm1
a8: 0f 16 4d d8 movhps -0x28(%rbp),%xmm1
ac: 0f 57 c0 xorps %xmm0,%xmm0
af: 0f 12 45 c0 movlps -0x40(%rbp),%xmm0
b3: 0f 16 45 c8 movhps -0x38(%rbp),%xmm0
b7: 0f 58 c1 addps %xmm1,%xmm0
ba: 0f 13 45 b0 movlps %xmm0,-0x50(%rbp)
be: 0f 17 45 b8 movhps %xmm0,-0x48(%rbp)

方法二:

    c.v = _mm_add_ps(a.v, b.v);
a1: 0f 57 c0 xorps %xmm0,%xmm0
a4: 0f 12 45 a0 movlps -0x60(%rbp),%xmm0
a8: 0f 16 45 a8 movhps -0x58(%rbp),%xmm0
ac: 0f 57 c9 xorps %xmm1,%xmm1
af: 0f 12 4d b0 movlps -0x50(%rbp),%xmm1
b3: 0f 16 4d b8 movhps -0x48(%rbp),%xmm1
b7: 0f 13 4d f0 movlps %xmm1,-0x10(%rbp)
bb: 0f 17 4d f8 movhps %xmm1,-0x8(%rbp)
bf: 0f 13 45 e0 movlps %xmm0,-0x20(%rbp)
c3: 0f 17 45 e8 movhps %xmm0,-0x18(%rbp)
/* Perform the respective operation on the four SPFP values in A and B. */

extern __inline __m128 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_add_ps (__m128 __A, __m128 __B)
{
return (__m128) __builtin_ia32_addps ((__v4sf)__A, (__v4sf)__B);
c7: 0f 57 c0 xorps %xmm0,%xmm0
ca: 0f 12 45 e0 movlps -0x20(%rbp),%xmm0
ce: 0f 16 45 e8 movhps -0x18(%rbp),%xmm0
d2: 0f 57 c9 xorps %xmm1,%xmm1
d5: 0f 12 4d f0 movlps -0x10(%rbp),%xmm1
d9: 0f 16 4d f8 movhps -0x8(%rbp),%xmm1
dd: 0f 58 c1 addps %xmm1,%xmm0
e0: 0f 13 45 90 movlps %xmm0,-0x70(%rbp)
e4: 0f 17 45 98 movhps %xmm0,-0x68(%rbp)

显然,使用内部 _mm_add_ps() 时生成的代码要大得多。为什么是这样?它不应该产生更好的代码吗?

最佳答案

真正重要的是 addps。在更实际的用例中,例如,您可能在循环中添加两个大的浮点 vector ,循环体将只包含 addps、两个加载和一个存储,以及一些标量用于地址算术的整数指令。在现代超标量 CPU 上,其中许多指令将并行执行。

另请注意,您在编译时禁用了优化,因此您不会获得特别高效的代码。试试 gcc -O3 -msse3 ...

关于c - 使用 sse 执行内在函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5276825/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com