sse2 指令集未启用

Posted

技术标签:

【中文标题】sse2 指令集未启用【英文标题】:sse2 instruction set not enabled 【发布时间】:2021-05-05 08:59:12 【问题描述】:
CC=g++
CFLAGS=-O3 -c -Wall
DFLAGS=-g -Wall
LDFLAGS= -lz -lm -lpthread

KSWSOURCE=ksw.c
ALGNSOURCES=main.cpp aligner.cpp graph.cpp  readfl.cpp hash.cpp form.cpp btree.cpp conLSH.cpp
INDSOURCES=whash.cpp genhash.cpp formh.cpp conLSH.cpp

INDOBJECTS=$(INDSOURCES:.cpp=.o) $(KSWSOURCE:.c=.o)
ALGNOBJECTS=$(ALGNSOURCES:.cpp=.o) $(KSWSOURCE:.c=.o)

INDEXER=conLSH-indexer
ALIGNER=conLSH-aligner

all: $(INDSOURCES) $(ALGNSOURCES) $(KSWSOURCE) $(ALIGNER) $(INDEXER)

$(ALIGNER): $(ALGNOBJECTS)
        $(CC)  $(ALGNOBJECTS) -o $@ $(LDFLAGS)

$(INDEXER): $(INDOBJECTS)
        $(CC)  $(INDOBJECTS) readfl.o -o $@ $(LDFLAGS)

debug:
        $(CC) $(DFLAGS) $(ALGNSOURCES) $(KSWSOURCE) $(LDFLAGS)

.cpp.o:
        $(CC) $(CFLAGS) $< -o $@
.c.o:
        $(CC) $(CFLAGS) $< -o $@
clean:
        rm -rf *.o $(ALIGNER) $(INDEXER) a.out

我有上面的 makefile,但我收到一个错误

/usr/lib/gcc/i686-linux-gnu/4.8/include/emmintrin.h:31:3: error: #error "SSE2 instruction set not enabled"
 # error "SSE2 instruction set not enabled"

根据我的理解和谷歌搜索,这是并行计算的标志。

我尝试从其他有相同问题的帖子中包括:

CXXFLAGS=-03 -c Wall -mfpmath=sse

或者:

set(CMAKE_CXX_FLAGS "$CMAKE_CXX_FLAGS -msse -msse2 -msse3")

但没有任何成功。你能帮忙吗?

我不确定 CXX 标志是否必要,因为很多(可能)级联错误都显示在 ksw 中,例如,

ksw.c:49:2: error: ‘__m128i’ does not name a type
  __m128i *qp, *H0, *H1, *E, *Hmax;

【问题讨论】:

您使用的是纯(手写)Makefile 还是 cmake?你是32位还是64位模式?你的 CPU 是否真的支持 SSE2(检查cat /proc/cpuinfo)? 【参考方案1】:

-msse2 是特定选项,因此如果您将构建脚本设置为实际执行此操作,则将其传递给 GCC 将起作用。 https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html#x86-Options

或者更好的是,使用-march=native 来启用您的 CPU 所拥有的一切,如果您是为本地使用而构建的,而不是用于分发可能必须在旧的但不是古老的 CPU 上工作的二进制文件。 (当然,如果您关心性能,为 32 位模式构建是很奇怪的。SSE2 是 x86-64 的基准。除非您的 CPU 太旧而无法支持 SSE2,例如 Pentium III。或者例如,有没有 SSE 的嵌入式 x86 CPU,例如 AMD Geode。在这种情况下,使用 -msse2 构建(成功)的二进制文件可能会因此类 CPU 上的非法指令而崩溃。)

-mfpmath=sse 只是告诉 GCC 使用 SSE 进行标量 FP 数学,假设 SSE 可用;与告诉 GCC 假设目标 CPU确实 支持 SSE2 无关。使用它也可以提高性能,但编译你的代码并不重要。

是的,像 __m128i 这样的 SSE1/2 内在类型只有在启用 SSE 时才会被定义,所以 error: ‘__m128i’ does not name a type 是一个明确的信号,表明 -msse 没有启用


如果使用 autoconf 之类的,也许使用这个:

./configure CPPFLAGS="-O3 -march=native -fno-math-errno"

如果您有 .c 文件和 .cpp,请设置 CFLAGS 和 CPPFLAGS。如果您将这些选项添加到您的 LD 选项中,更多选项(如 -flto)可能有助于优化(链接时的跨文件内联)。以及任何其他优化选项,如-ffast-math,如果您想使用它。或者至少-fno-trapping-math 帮助了一些人,而且 GCC 已经做了违反语义陷阱数学应该提供的优化。请参阅this Q&A 回复:-fno-trapping-math -fno-math-errno 基本上在任何地方都可以安全使用,即使在依赖于严格 FP(如 Kahan 求和)的代码中也是如此。

【讨论】:

添加 -march=native 确实修复了所有问题。所有级联错误都消失了。【参考方案2】:

这对我也有用:

./configure CPPFLAGS="-march=native"

【讨论】:

以上是关于sse2 指令集未启用的主要内容,如果未能解决你的问题,请参考以下文章

在 Visual Studio 中检测 SSE/SSE2 指令集的可用性

是否启用了 SSE2 指令?

SSE、SSE2、SSE3指令集的区别?

启用 arch:SSE2 使程序变慢

sse2_FloatToInt

指令集的相关问题!