是否启用了 SSE2 指令?
Are SSE2 instructions enabled?
我有一个非常简单的 c++ 代码(我实际正在做的事情的最小示例(,使用 sse2 内部函数。
#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 使用 x87fld
/faddp
实现+
运算符。
__m128d
被定义为具有两个double
元素的GNU C本机向量,并且您没有使用任何内部函数。 如果你使用_mm_set_pd
或_mm_add_pd
而不是 GNU 扩展语法,后者将它们用作带有{}
支撑的 init 列表和+
运算符的本机向量,你会得到:
<source>:5:13: error: SSE register return with SSE disabled
__m128d c = _mm_add_pd(a, b);
有趣的是,即使禁用了SSE2,它仍然会解析xmmintrin.h
而不会出错,但仅在-O0
. 启用优化后,它会注意到所有这些(内联(函数都会在禁用 SSE 的 SSE 寄存器中返回,即使您不调用它们。
您可以通过自己定义矢量类型来解决此问题,例如typedef double v2d __attribute__((vector_size(16)))
.
在 Godbolt 编译器资源管理器上,gcc8.2 -m32
配置默认启用 SSE2(即使 SSE2 通常不是32 位的基线(。
但是 gcc6.3 -m32 默认情况下不启用 SSE2,如-Q --help=target
输出所示。
当SSE2被禁用时,我尝试过的任何组合都没有让gcc发出addpd
(无论是显式启用还是干脆没有启用-m32
(。 AFAIK,那将是一个错误。
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 无法编译 rtmidi 测试 cmidiin.cpp 文件, 非法指令
- C++:对不存在的命名空间使用命名空间指令
- 函数名是c中该函数的第一条指令的地址吗
- 错误:无效的预处理指令 #i 的意思是 #if?
- 组装指令中乘法的下部和上部是什么
- OpenMP 与有序和关键指令并行
- C++中的移动分配出现问题.非法指令: 4.
- 嵌套命名空间的"using"指令,但需要命名内部命名空间
- C++CMake编译指令与
- 使用宏扩展的泛型:为什么指令缓存使用不当?
- 使用 SSE2 和 AVX2 编译库
- 如何在 c++ 中确定一条指令(以字节为单位)在哪里结束,另一条指令从哪里开始?
- AVX 指令中寄存器和指针之间的客观差异
- 是否启用了 SSE2 指令?
- i5-2500k 上的 cpuid 指令:未设置 MMX、SSE、SSE2 位
- 使用 qmake 成功编译 SSE 指令(但 SSE2 不被识别)
- 检测Visual Studio中SSE/SSE2指令集的可用性
- #error "SSE2 指令集未启用"时包含 <emmintrin.h>
- SSE/SSE2 指令的打包和解包数据