我们有一个基于 centos 的 docker 镜像,它使用 gcc 5.4 来构建一个大型的 C++ 代码库。 docker 镜像从源代码构建和安装 gcc。由于我们的私有(private) docker 注册表中的一些数据丢失,我们不得不重建/将此 docker 镜像推送回我们的注册表,并开始发现使用此 docker 镜像的本地构建存在问题。
我们看到的错误是:
/usr/include/c++/5.4.0/limits:1601:7: internal compiler error: Illegal instruction
max() _GLIBCXX_USE_NOEXCEPT { return __FLT_MAX__; }
^
0xa4f0cf crash_signal
../../gcc-5.4.0/gcc/toplev.c:383
我的理论是,这个错误是由于运行构建的底层 CPU 的架构造成的,因为我们是从源代码构建 GCC。
以前,我们有一个基于 Xeon E5 v3 CPU(Haswell 架构)的 CI 基础架构。这个 docker 镜像的构建最初是在其中一台 CI 机器上完成的,因此在本地 Haswell 开发箱上运行良好。我们的 CI 基础设施已经迁移到使用 Xeon Platinum CPU(Skylake 架构)。当我重建图像时,我是在我们的一个新 Skylake 盒子上这样做的。
由于我有一个较新的开发箱,我有一个基于 Broadwell 的 CPU,无法在本地重现该问题。我们的 CI 构建运行良好。本地出现此错误的用户使用的是 Haswell CPU。
我的理论合理吗?我已经要求用户在他们的 CPU 上本地构建我们的 docker 镜像并测试结果,但是有没有更通用的方法来解决这个问题?
我遇到了 this answer这让我指向了this documentation其中指出我可以通过 -march=***
自己指定处理器架构。我的想法源于此:
- 在构建 GCC 时设置
-march=haswell
以防止启用较新的指令集 - 在为 Haswell 上不可用但 Broadwell/Skylake 上存在的指令集扩展构建 GCC 时设置
-mno-***
。
作为引用,lscpu
的输出具有这些 Broadwell 标志,这些标志在 Haswell 盒子上不存在(具有关联的 -mno-***
标志):
3dnowprefetch
hle
rtm
rdseed
adx
smap
arch_capabilities
是否值得测试这些想法中的任何一个是否解决了这个问题?我希望得到一些外部输入,因为这个 docker build 的开发循环相当长,老实说,我不知道这些 -m
标志会解决问题。
另外,作为引用,下面是我们构建 gcc 的方式:
# build/install gcc
RUN tar xvf /tmp/archive/gcc-5.4.0.tar.gz && \
mkdir gcc-build && \
pushd gcc-build && \
../gcc-5.4.0/configure --prefix=/usr --enable-languages=c,c++,fortran --disable-multilib --with-gmp=/usr --with-mpfr=/usr --with-mpc=/usr && \
make -j32 && \
popd && \
yum remove -y gcc gcc-c++ gcc-gfortran && \
pushd gcc-build && \
make install && \
popd && \
rm -rf gcc-build gcc-5.4.0
最佳答案
如维基百科 (https://en.wikipedia.org/wiki/List_of_Intel_CPU_microarchitectures) 所示,Skylake 位于 Broadwell 之后,它本身位于 Haswell 之后。
因此,在 Skylake 上构建的此类构建可能无法在较旧的 CPU 上运行,因此您应该始终将 -march=haswell
添加到您的默认构建中,以生成必须在 Haswell 及更高版本上运行的二进制文件。
使用 -march
为您的最小平台调整架构,因为您知道在启用额外的指令集时可能会有数值差异。
您还可以使用 -mtune
指定您将优化代码的目标(意味着在此平台上,代码应该更快)。您可以混合使用两者,只要 march
低于 mtune
。
关于c++ - 这个 g++ 'illegal instruction error' 是由于用于构建 GCC 的 CPU 架构造成的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53563791/