gpt4 book ai didi

c++ - 是否启用了 SSE2 指令?

转载 作者:行者123 更新时间:2023-11-30 04:58:08 25 4
gpt4 key购买 nike

我有一个使用 sse2 内在函数的非常简单的 C++ 代码(我实际正在做的一个最小示例)。

#include <xmmintrin.h>
int main(){
__m128d a = {0,0};
__m128d b = {1,1};
__m128d c = a + b;
int t = c[0] >= 1;
return t;
}

我想检查加法是否确实编译为矢量化指令。我用 g++ -S test.cpp

编译文件

我对这件事的理解是,如果我不将 msse2 标志设置为 g++,则不会启用 sse2。 g++ -Q --help=target

的结果似乎证实了这一点
  -msse                             [disabled]
-msse2 [disabled]
-msse2avx [disabled]
-msse3 [disabled]
-msse4 [disabled]
-msse4.1 [disabled]
-msse4.2 [disabled]
-msse4a [disabled]

但是看汇编代码,好像用到了addpd指令。

main:
.LFB499:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $80, %rsp
movq %fs:40, %rax
movq %rax, -8(%rbp)
xorl %eax, %eax
pxor %xmm0, %xmm0
movaps %xmm0, -48(%rbp)
movapd .LC0(%rip), %xmm0
movaps %xmm0, -32(%rbp)
movapd -48(%rbp), %xmm0
addpd -32(%rbp), %xmm0
movaps %xmm0, -64(%rbp)
movsd -64(%rbp), %xmm0
pxor %xmm1, %xmm1
ucomisd %xmm1, %xmm0
setnb %al
movzbl %al, %eax
movl %eax, -68(%rbp)
movl -68(%rbp), %eax
movq -8(%rbp), %rdx
xorq %fs:40, %rdx
je .L3
call __stack_chk_fail
.L3:
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE499:
.size main, .-main
.section .rodata
.align 16
.LC0:
.long 0
.long 1072693248
.long 0
.long 1072693248
.ident "GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.10) 5.4.0 20160609"
.section .note.GNU-stack,"",@progbits

我在这里看到了一个矛盾,这让我觉得有些地方我不明白。是否开启sse2?

最佳答案

我无法重现你的结果。

x86-64 g++ 确实启用了 -msse-msse2。您可以使用 -mno-sse 在 64 位模式下禁用 SSE 代码生成(即使 SSE2 是 x86-64 的基线),在这种情况下 gcc 实现 + 运算符与 x87 fld/faddp

__m128d 被定义为具有两个 double 元素的 GNU C native vector ,并且您没有使用任何内在函数。如果您使用 _mm_set_pd_mm_add_pd 而不是 GNU 扩展语法,后者将它们用作带有 {} 大括号初始化列表和 + 运算符,你会得到:

<source>:5:13: error: SSE register return with SSE disabled
__m128d c = _mm_add_pd(a, b);

有趣的是,即使禁用了 SSE2,它仍会无错误地解析 xmmintrin.h,但仅限于 -O0。启用优化后,它会注意到所有这些(内联)函数在禁用 SSE 的情况下返回到 SSE 寄存器中,即使您不调用它们也是如此。

你可以通过自己定义一个 vector 类型来解决这个问题
typedef double v2d __attribute__((vector_size(16)))


On the Godbolt compiler explorer , gcc8.2 -m32 配置为默认启用 SSE2(尽管 SSE2 通常不是 32 位的基线)。

但是 gcc6.3 -m32 默认情况下不启用 SSE2,如您在 -Q --help=target 输出中所见。

当 SSE2 被禁用时(无论是明确启用还是根本不启用 -m32),我尝试的任何组合都没有让 gcc 发出 addpd。据我所知,那将是一个错误。

关于c++ - 是否启用了 SSE2 指令?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51789424/

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