Почему процессор Intel Haswell XEON периодически неправильно вычисляет FFT и ART?

В последние дни я наблюдал за поведением своего нового рабочего места, которое не мог объяснить. Проведя небольшое исследование этой проблемы, возможно, есть ошибка в архитектура INTEL Haswell, а также в текущем поколении Skylake.

Прежде чем писать о возможной ошибке, позвольте мне дать вам обзор используемого оборудования, программного кода и самой проблемы.

Спецификация оборудования рабочей станции

  • INTEL Xeon E5-2680 V3 2500 МГц 30 МБ кэш-памяти 12 ядер
  • Supermicro SC745 BTQ -R1K28B-SQ
  • 4 x 32 ГБ ECC Registered DDR4-2133 Ram
  • Твердотельный накопитель INTEL серии 730 480 ГБ
  • NVIDIA Тесла C2075
  • NVIDIA ТИТАН

Операционная система и программный код, о котором идет речь

В настоящее время я использую 64-битную настольную версию Ubuntu 15.04, установлены последние обновления и ядро. Помимо использования этой машины для разработки ядер CUDA и прочего, я недавно протестировал чистую программу C. Программа выполняет своего рода модифицированное ART на довольно больших входных наборах данных. Таким образом, код выполняет некоторые БПФ и требует довольно много времени для завершения вычислений. В настоящее время я не могу публиковать / ссылаться на какой-либо исходный код, так как это текущее исследование, которое не может быть опубликовано. Если вы не знакомы с ART, просто объясните, что он делает. ART - это метод, используемый для восстановления данных, полученных с компьютерного томографа, для получения видимых изображений для диагностики. Таким образом, наша версия кода восстанавливает наборы данных размером, например, 2048x2048x512. До сих пор в этом не было ничего особенного, ни ракетостроения. После нескольких часов отладки и исправления ошибок код был протестирован на эталонных результатах, и мы можем подтвердить, что код работает так, как должен. Единственная библиотека, которую использует код, - это стандартная math.h. Никаких специальных параметров компиляции, никаких дополнительных библиотечных вещей, которые могут вызвать дополнительные проблемы.

Наблюдая за проблемой

Код реализует ART, используя метод минимизации проекций, необходимых для восстановления данных. Итак, давайте предположим, что мы можем восстановить один фрагмент данных, включающий 25 проекций. Код запускается с точно такими же входными данными на 12 ядрах. Обратите внимание, что реализация не основана на многопоточности, на данный момент запущено 12 экземпляров программы. Я знаю, что это не лучший способ сделать это, настоятельно рекомендуется правильное управление потоками, и это уже в списке улучшений :)

Поэтому, когда мы запускаем по крайней мере два экземпляра программы (каждый экземпляр работает с отдельным срезом данных), результаты некоторых прогнозов случайным образом ошибочны. Чтобы получить представление о результатах, см. Таблицу 1. Обратите внимание, что входные данные всегда одни и те же.

Запуск только одного экземпляра кода с участием одного ядра ЦП, все результаты верны. Даже при выполнении некоторых прогонов с использованием одного ядра ЦП результаты остаются правильными. Только при включении хотя бы двух или более ядер генерируется шаблон результата, как показано в Таблице 1.

«Таблица

Выявление проблемы

Хорошо, потребовалось несколько часов, чтобы понять, что на самом деле идет не так. Итак, мы просмотрели весь код, большинство этих проблем начинаются с незначительной ошибки реализации. Но нет (конечно, мы не можем ни доказать отсутствие ошибок, ни гарантировать это). Для проверки нашего кода мы использовали две разные машины:

  • (Machine1) Четырехъядерный процессор Intel Core i5 (модель конца 2009 г.)
  • (Machine2) Виртуальная машина, работающая на 6-ядерном процессоре Intel XEON SandyBridge

удивительно, что и Machine1, и Machine2 дают всегда правильные результаты. Даже при использовании всех процессорных ядер результаты остаются правильными. Ни одного неверного результата из более чем 50 запусков на каждой машине. Код был скомпилирован на каждой целевой машине без параметров оптимизации или каких-либо конкретных настроек компилятора. Итак, чтение новостей привело к следующим выводам:

Итак, ребята из Prime95 и Сообщество Мерсенна кажется первым, кто обнаружит и определит это неприятный баг. Упомянутые сообщения и новости подтверждают подозрение, что проблема существует только при большой нагрузке. Следуя своим наблюдениям, я могу подтвердить такое поведение.

Вопросы)

  • Наблюдали ли вы / сообщество эту проблему на процессорах Haswell, а также на процессорах Skylake?
  • Поскольку gcc выполняет оптимизацию AVX (2) по умолчанию (когда это возможно), отключение этой оптимизации поможет?
  • Как я могу скомпилировать свой код и убедиться, что любая оптимизация, на которую может повлиять эта ошибка, отключена? Пока я читал только о проблеме с использованием набора команд AVX2 в архитектурах Haswell / Skylake.

Решения?

Хорошо, я могу отключить все оптимизации AVX2. Но это замедляет мой код. Intel может выпустить обновление BIOS для производителей материнских плат, которое изменит микрокод в процессорах Intel. Поскольку это кажется аппаратной ошибкой, это может стать интересным даже при обновлении микрокода ЦП. Я думаю, что это может быть допустимый вариант, поскольку процессоры Intel используют некоторые механизмы преобразования RISC в CISC, контролируемые микрокодом.

РЕДАКТИРОВАТЬ: Techreport.com - Исправление побуждает Intel отключить TSX в Haswell, ранних процессорах Broadwell Будет проверять версию микрокода в моем процессоре.

EDIT2: На данный момент (19.01.2016 15:39 CET) Memtest86 + v4.20 работает и тестирует память. Поскольку это, похоже, займет некоторое время, завтра я обновлю сообщение с результатами.

EDIT3: На данный момент (21.01.2016 09:35 CET) Memtest86 + завершил два прогона и прошел. Ни одной ошибки памяти. Обновлен микрокод процессора с revision=0x2d до revision=0x36. В настоящее время готовим исходный код к выпуску здесь. Состоит проблема с неправильными результатами. Поскольку я не являюсь автором рассматриваемого кода, я должен дважды проверить, чтобы не размещать код, который мне не разрешен. Я также использую рабочую станцию ​​и обслуживаю ее.

EDIT4: (22.01.2016) (12:15 CET) Вот Makefile, используемый для компиляции исходного кода:

# VARIABLES ==================================================================
CC = gcc
CFLAGS = --std=c99 -Wall
#LDFLAGS = -lm -lgomp   -fast -s -m64 
LDFLAGS = -lm 

OBJ = ArtReconstruction2Min.o


# RULES AND DEPENDENCIES ====================================================

# linking all object files
all: $(OBJ)
  
    $(CC) -o ART2Min $(OBJ) $(LDFLAGS)         

    
# every o-file depends on the corresonding c-file, -g Option bedeutet Debugging Informationene setzen
%.o: %.c
    $(CC)  -c -g $<  $(CFLAGS)
  
    
# MAKE CLEAN =================================================================
clean: 
    rm -f *.o
    rm -f main

и выход gcc -v:

gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.9/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.9.2-10ubuntu13' --with-bugurl=file:///usr/share/doc/gcc-4.9/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.9 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.9 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.9-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.9-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.9-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.9.2 (Ubuntu 4.9.2-10ubuntu13) 

person semm0    schedule 19.01.2016    source источник
comment
Почему отрицательные голоса? Это отличный и актуальный вопрос! Попробую воспроизвести на аналогичной установке.   -  person rzo1    schedule 19.01.2016
comment
Вы подтвердили ошибку с Prime95? Кроме того, просмотренные мною страницы, похоже, указывают на то, что процессор должен зависнуть, а не выдавать неверные результаты незаметно. Вы рассматривали другую причину, например, неисправная оперативная память?   -  person Peter - Reinstate Monica    schedule 19.01.2016
comment
пока нет, но сделаю в следующие несколько часов. Опубликую результаты, когда я закончу с этим. Также проверим версию микрокода моего процессора, чтобы проверить, связана ли эта проблема с ошибкой / проблемой TSX. edit: также будет выполнять проверку ОЗУ, чтобы убедиться, что ОЗУ работает правильно или нет.   -  person semm0    schedule 19.01.2016
comment
The code is started with exactly the same input data on 12 cores ... от этого практически нет никакой пользы, и на самом деле это .... довольно тупо. Прости. 11 из ваших 12 ядер выполняют бесполезную избыточную работу все.   -  person specializt    schedule 19.01.2016
comment
@specializt ну, поскольку его тесты показывают, что 11 из 12 идентичных ядер НЕ делают одно и то же, несмотря на то, что они должны это делать, придает этой настройке реальный смысл. Имея спорадические сбои при расчетах, довольно сложно придумать такую ​​глупую вещь, чтобы выявить, что некоторые из основных предположений (код будет вести себя одинаково для идентичных входных данных при любой нагрузке на любое ядро) ложны.   -  person DThought    schedule 19.01.2016
comment
Тот факт, что он мог или не мог обнаружить либо аппаратную ошибку (очень маловероятно), либо аппаратный дефект (очень вероятно) посредством бессмысленных избыточных операций, не делает этот подход более разумным. То, что он сейчас испытывает, называется удачей - он также обнаружил бы ту же проблему (-и) с инструментами тестирования, интенсивно использующими процессор, такими как IBT или prime95 с днями выполнения. @ semm0: загрузите и запустите IBT - если ваша машина зависает, вы знаете, что проблема связана либо с рассеянием тепла, либо даже с аппаратным дефектом - спорадические ошибки вычислений довольно распространены в обоих случаях.   -  person specializt    schedule 19.01.2016
comment
intelburntest.en.lo4d.com   -  person specializt    schedule 19.01.2016
comment
Никаких специальных параметров компиляции. Откуда вы знаете? Какие у вас варианты компиляции? Вы говорите «Как делает gcc для оптимизации AVX (2) по умолчанию». Нет. По умолчанию он использует SSE2 только в 64-битном режиме. Вы, должно быть, добавили несколько опций. Вы спрашиваете, поможет ли отключение этой оптимизации? Почему бы тебе не проверить это? Опять же, укажите параметры компиляции, а также свой компилятор и версию.   -  person Z boson    schedule 19.01.2016
comment
Ваш make-файл даже не использует оптимизацию. Я не вижу никаких флагов, которые использовали бы что-то большее, чем SSE2. Вы смотрели сборку, чтобы узнать, какие инструкции используются? Вы пробовали свой код с включенной оптимизацией, например. -O3. Как вы работаете на нескольких ядрах? Вы используете OpenMP? Я вижу флаг -gomp для компоновщика (закомментирован).   -  person Z boson    schedule 22.01.2016
comment
В вашем коде используются какие-либо глобальные переменные состояния? Если это так, то даже если несколько потоков запускают одну и ту же функцию, и если они записывают в глобальную переменную состояния, это может дать неправильный результат.   -  person Z boson    schedule 22.01.2016


Ответы (2)


РЕДАКТИРОВАТЬ: проблема решена. Я должен выразить огромные извинения сообществу и большое спасибо за ваши советы. Извините анонимного пользователя, который, похоже, участвует в разработке ядра. Что случилось? Еще два дня мы потратили на отладку и возиться с программным кодом. Проблем с реализацией не обнаружено. НО: в основном коде задействована другая вспомогательная программа. Эта вспомогательная программа вычисляет веса для алгоритма ART по запросу. Итак, после отладки и тестирования эта вспомогательная программа испортилась при запуске как минимум 4 процессов. Так что это была НЕ проблема ядра / оборудования, а проблема программного обеспечения (доступа к памяти).

Уроки выучены:

  1. Отлаживайте каждый инструмент, участвующий в процессе расчета.
  2. Микрокод устарел. Об этом сообщает SuperMicro.
  3. Ubuntu 15.04, возможно, потребуются дополнительные инструменты, чтобы все ядра процессора работали на полной скорости. Достигнуто путем установки Ubuntu 14.04 - все ядра работают на частоте 2,5 ГГц.
  4. Мне нужно выпить пива, если мы когда-нибудь встретимся на конференции.

Итак, после трех дней размышлений, тестирования и возни с машиной сегодня я обнаружил следующие наблюдения:

  1. В Ubuntu 15.04 процессор работает с частотой 420-650 МГц на ядро. Хорошо, я подумал, что это вариант энергосбережения, поэтому я следовал различным руководствам, чтобы установить максимальную скорость (2,50 ГГц). Это не сработало. Проверено с cpufreq-utils.

  2. Результаты по-прежнему оставались неверными после нескольких тестов на этой машине. Другие машины (i5, i7, XEON) показали правильные результаты.

  3. Я читал, что другие пользователи испытывали проблемы с Ubuntu 15.04 и частотой процессора. Поэтому я решил подключить SSD и установить Ubuntu 14.04. Проверил еще раз, какая сейчас частота процессора ... и она показала 2,50 ГГц, как я и ожидал.

  4. Снова запустил алгоритм реконструкции (который теперь вроде в 4-5 раз быстрее, чем на Ubuntu 15.04) и стал ждать результатов. Хорошо. Теперь результаты верны! Я дважды проверил, запустил 9 процессов и сравнил результаты. Все еще правильно.

Поэтому я могу только предположить, что в Ubuntu 15.04 / ядре может быть проблема с использованием Speedstep в этом процессоре. ЦП в версии 15.04 все время работал в диапазоне 420–650 МГц, при этом минимальная частота процессора ожидается на уровне 1,20 ГГц, а максимальная частота процессора - 3,30 ГГц. Если кому-то нужен чек, я могу предложить исходный код и пример данных, ведущих к этой проблеме.

Извините за то, что подозреваю, что это ошибка процессора.

РЕДАКТИРОВАТЬ: после еще нескольких тестов проблема решена только для некоторых сценариев, но еще не для всех. Я проведу еще тесты.

person semm0    schedule 22.01.2016
comment
Вы пробовали компилировать с использованием удобных параметров компилятора? Нравится -O3 -march=native? Это должно привести к увеличению скорости в 2-10 раз, в зависимости от того, является ли пропускная способность памяти узким местом и насколько хорошо ваш код автовекторизует с AVX / AVX2. Обработка чисел с помощью -O0 - глупость, если только это не был единственный способ воспроизвести проблему. Также обратите внимание, что Ubuntu 15.10 отсутствует с 2015/10 (конечно). Я бы попробовал перейти на это. (особенно, поскольку новые компиляторы, такие как gcc 5.2, лучше старых). - person Peter Cordes; 22.01.2016
comment
Спасибо за комментарий, Питер. Обычно я разрабатываю с использованием CUDA 7.5, и в настоящее время это работает только 14.04 или 15.04 - я не тестировал 15.10 ... Спасибо за указание на оптимизацию компилятора. Начал с ускорения примерно на 30-40%. - person semm0; 22.01.2016
comment
Получаете ли вы правильные результаты при включенной оптимизации? - person Z boson; 22.01.2016

Ошибка Skylake-S / U prime95 находится в блоке AVX (не AVX2). Зафиксировано на микрокодах 0x56 (наверное) и 0x6a (точно). Такая ошибка в Haswell маловероятна, но возможна (особенно в Intel после 2014 г., где «проверка» стала нежелательной платой за качество, а не арендатором).

Haswell имеет исправления, связанные с блоком AVX, хотя HSE58 вряд ли будет задействован (он только замедляет работу блока AVX). Однако постарайтесь поместить несколько инструкций MFENCE перед вычислениями AVX2. Если это исправит, немедленно сообщите об этом, это означает, что нам нужно MFENCE все IRET в ядре (HSE105).

Ваш процессор имеет подпись 0x306f2. Убедитесь, что у вас версия микрокода 0x36 или более поздняя, ​​этот микрокод входит в состав Intel «Пакет обновлений микрокода Linux» от 06.11.2015.

РЕДАКТИРОВАТЬ: на самом деле это не было ответом, поэтому вместо этого я должен был сделать это комментарием. Я приношу извинения. Поскольку обновления микрокода было недостаточно для устранения проблемы, это все еще может быть новая ошибка, старая, но не устраненная ошибка или что-то совсем другое (например, ошибка кода или ошибка генерации кода gcc).

person anonymous    schedule 20.01.2016
comment
Спасибо за ваш ответ. В настоящее время работаю над сбором всей информации, необходимой для комментариев сверху. Информация о микрокоде (эта информация будет позже добавлена ​​в качестве дополнительного РЕДАКТИРОВАНИЯ к исходному вопросу): микрокод: CPU0 sig = 0x306f2, pf = 0x1, revision = 0x2d - person semm0; 20.01.2016
comment
Обновите этот микрокод и повторно протестируйте ... вы можете использовать более современный пакет intel-microcode в Debian или Ubuntu Xenial Xerus напрямую: просто загрузите .deb из Debian или Ubuntu и dpkg -i it. Убедитесь, что initramfs обновлен, и перезагрузитесь. И действительно, жалуйтесь на Supermicro, чтобы заставить их обновить BIOS. - person anonymous; 20.01.2016
comment
Хорошо, установлено обновление микрокода: microcode: CPU0 sig = 0x306f2, pf = 0x1, revision = 0x36 Извините, на прошлой неделе семестра были презентации студентов. Теперь перезапустим вычисления, чтобы увидеть результаты. Я постараюсь обновить вас примерно за 4-5 часов. - person semm0; 20.01.2016
comment
Проблема все еще существует после обновления микрокода. Нужно поспать ... Вернусь через 9 часов. - person semm0; 21.01.2016
comment
@ semm0, вы еще не указали свои параметры компиляции. - person Z boson; 22.01.2016