Является ли эта ошибка ++ недопустимой инструкцией из-за архитектуры процессора, который использовался для сборки GCC? - PullRequest
0 голосов
/ 30 ноября 2018

У нас есть образ докера на основе centos, который использует gcc 5.4 для создания большой базы кода C ++.Образ docker создает и устанавливает gcc из исходного кода.Из-за некоторой потери данных в нашем частном реестре докеров нам пришлось перестроить / отправить этот образ докера обратно в наш реестр, и мы начали видеть проблему с локальными сборками, использующими этот образ докера.

Ошибка, которой мы являемсявидение таково:

/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

Моя теория заключается в том, что эта ошибка связана с архитектурой базового процессора, на котором выполняется сборка, поскольку мы собираем GCC из исходного кода.

Ранее мы имелиинфраструктура CI, основанная на процессорах Xeon E5 v3 (архитектура Haswell).Построение этого образа докера изначально было сделано на одной из этих CI-машин и, таким образом, отлично работало на локальных блоках разработки Haswell.С тех пор наша инфраструктура CI перешла на использование процессоров Xeon Platinum (архитектура Skylake).Когда я перестроил образ, я сделал это на одном из наших новых блоков Skylake.

Поскольку у меня более новый блок разработки, у меня есть процессор на базе Broadwell и я не могу воспроизвести проблему локально.Наши сборки CI работают отлично.Пользователь, получающий эту ошибку локально, имеет процессор Haswell.

Является ли моя теория обоснованной? Я попросил пользователя построить наш образ докера локально на своем процессоре и проверить результат, но есть лиспособ обойти это более обобщенно?

Я встречал этот ответ , который указал мне на эту документацию , в которой говорится, что я могу сам указать архитектуру процессора через-march=***.Мои идеи вытекают из этого:

  1. Установить -march=haswell при сборке GCC, чтобы запретить включение новых наборов команд
  2. Установить -mno-*** при сборке GCC для расширений набора команд, которыенедоступны в Haswell, но существуют в Broadwell / Skylake.

Для справки, вывод lscpu имел эти флаги Broadwell, которых не было в блоке Haswell (которые связаны -mno-*** flags):

3dnowprefetch
hle
rtm
rdseed
adx
smap
arch_capabilities

Стоит ли тестировать, если какая-либо из этих идей решает проблему?Я надеюсь получить некоторый внешний вклад, поскольку цикл разработки для этой сборки докера довольно длинный, и я, честно говоря, понятия не имею, что эти -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

1 Ответ

0 голосов
/ 30 ноября 2018

Как указано в википедии (https://en.wikipedia.org/wiki/List_of_Intel_CPU_microarchitectures), Skylake расположен позади Broadwell, сам позади Haswell.

Так как такая сборка на Skylake может не работать на старом процессоре, и вы всегда должныдобавьте -march=haswell к вашим сборкам по умолчанию, которые производят двоичные файлы, которые должны работать на Haswell и более поздних версиях.

Настройте архитектуру для своей минимальной платформы с помощью -march, зная, что у вас могут быть числовые различия, если вы включите дополнительные наборы команд.

Вы также можете использовать -mtune, чтобы указать цель, для которой вы будете оптимизировать свой код (это означает, что на этой платформе код должен быть быстрее). Вы можете смешивать оба, пока marchниже mtune.

...