TL: DR: KNL (Knight's Landing) только хорошо работает с кодом, специально скомпилированным для него, и, таким образом, получает гораздо большее ускорение, потому что спотыкается из-за плохо работающего «универсального»code.
Coffee Lake ускоряется только в 2 раза со 128-битного SSE2 до 256-битного AVX, оптимально выполняя как «универсальный», так и целевой код.
Основные процессоры, такие как Coffee Lake, - одиниз целей, которые заботятся о «общей» настройке в современных компиляторах, и они не имеют много слабых мест в целом.Но КНЛ нет;ICC без каких-либо опций не заботится о KNL
Вы предполагаете, что базовая линия для ваших ускорений составляет скаляр .Но без каких-либо опций, таких как -march=native
или -xCORE-AVX2
, компилятор Intel (ICC) все равно будет автоматически векторизоваться с SSE2, потому что это базовый показатель для x86-64.
-xCORE-AVX2
не включает авто-векторизацию, он просто дает векторизации еще больше инструкций для игры.Уровень оптимизации (включая авто-векторизацию) контролируется -O0
/ -O2
/ -O3
, а для FP - строгим и быстрым fp-model
.Компилятор Intel по умолчанию использует полную оптимизацию с -fp-model fast=1
(на один уровень ниже fast=2
), так что это что-то вроде gcc -O3 -ffast-math
.
Но без дополнительных опций он может использовать только базовый набор инструкций, который дляx86-64 это SSE2.Это все же лучше, чем скаляр.
SSE2 использует 128-битные регистры XMM для упакованной двойной математики с той же пропускной способностью, что и AVX (на вашем i5 Coffee Lake), но вдвое меньше работы на инструкцию .(И у него нет FMA, поэтому компилятор не мог заключить какие-либо операции + добавления в вашем источнике в инструкции FMA, как это могло бы быть с AVX + FMA).
Так что фактор2 Ускорение на вашем процессоре Coffee Lake - это именно то, что вы должны ожидать для простой проблемы, которая является просто узким местом в пропускной способности векторного мульти / добавления / FMA SIMD (не память / кэш или что-либо еще).
Ускорение зависитна то, что делает ваш код.Если вы ограничены в пропускной способности памяти или кэша, более широкие регистры лишь немного помогают лучше использовать параллелизм памяти и поддерживать ее насыщенность.
А AVX + AVX2 добавляет более мощные тасовки, смеси и другие интересные вещи, но для простых задачс чистой вертикальной SIMD, которая не помогает.
Таким образом, реальный вопрос - Почему AVX512 помогает более чем в 4 раза по KNL? 8 double
элементов на инструкцию AVX512 SIMDпри высадке Найта, по сравнению с 2 с SSE2, ожидаемое ускорение в 4 раза, если бы пропускная способность команд была такой же.Предполагая, что общее количество команд было идентичным с AVX512.(Но это не так: при той же развертке цикла количество векторной работы на цикл увеличивается с увеличением векторов и других факторов.)
Трудно сказать точно, не зная, каким исходным кодом вы быликомпилирование.AVX512 добавляет некоторые функции, которые могут помочь сохранять инструкции, такие как операнды источника широковещательной памяти вместо того, чтобы требовать отдельной широковещательной загрузки в регистр.
Если ваша проблема связана с каким-либо делением , KNL работает очень медленноFP-деление с полной точностью, и обычно следует использовать инструкцию приближения AVX512ER (28-битная точность) + итерация Ньютона-Рафсона (пара FMA + mul), чтобы удвоить это значение, давая почти полное double
(53-битное значение, включая 1 неявный бит).-xMIC-AVX512
включает AVX512ER и устанавливает параметры настройки таким образом, чтобы ICC фактически выбрал его использование.
(В отличие от этого, пропускная способность 256-разрядного деления Coffee Lake AVX ничуть не лучше, чем пропускная способность 128-разрядного деления в два разаза цикл, но без AVX512ER не существует эффективного способа использования Newton-Raphson для double
).См. деление с плавающей точкой против умножения с плавающей точкой - числа Скайлэйка относятся к вашему Coffee Lake.
AVX / AVX512 может избежать дополнительных movaps
инструкций для копирования регистров , что очень помогает для KNL (каждая инструкция, которая не является mul / add / FMA, требует пропускной способности FP, потому что она имеет 2- FMA с тактовой частотой, но только максимальная пропускная способность команд по 2 такта).(https://agner.org/optimize/)
KNL основан на маломощном ядре Silvermont (именно так они устанавливают так много ядер на один чип).
В отличие от этого, у Coffee Lake гораздо более мощный фронт-конечная и внутренняя пропускная способность выполнения: в стойле имеется 2 FMA / мул / сложение на тактовую частоту, но 4 на общую тактовую пропускную способность, поэтому есть место для выполнения некоторых не-FMA инструкций без потери пропускной способности FMA.
Другие замедления при выполнении инструкций SSE / SSE2 на KNL (Xeon Phi)
KNL создан специально для запуска кода AVX512. Они не тратят впустую транзисторы, что делает его эффективным для выполнения устаревшего кода, который не был скомпилированспециально для него (с -xMIC-AVX512
или -march=knl
).
Но ваше Coffee Lake - это основное ядро настольного компьютера / ноутбука, которое должно быстро запускать любые прошлые или будущие двоичные файлы, включая код, который использует только «устаревшее»«Кодировки инструкций SSE2, а не AVX.
Инструкции SSE2, которые записывают регистр XMM, оставляют верхние элементы соответствующего регистра YMM / ZMMбез изменений.(Регулятор XMM - это младшие 128 битов полного векторного регистра).Теоретически это создаст ложную зависимость при запуске устаревших инструкций SSE2 на процессоре, который поддерживает более широкие векторы.(Основные процессоры Intel, такие как семейство Sandybridge, избегают этого с помощью смены режимов или фактических ложных зависимостей Skylake, если вы не используете vzeroupper
правильно. См. Почему этот код SSE в 6 раз медленнее без VZEROUPPER на Skylake? для сравнения 2 стратегий).
KNL действительно , по-видимому, имеет способ избежать ложных зависимостей: согласно тестированию Агнера Фога ( в его руководстве по микроархам )он описывает это как частичное переименование регистров, которое делает семейство P6, когда вы записываете в целочисленные регистры, такие как AL.Вы получаете только частичный регистр, когда читаете полный регистр.Если это верно, то код SSE2 должен нормально работать на KNL, потому что нет кода AVX, читающего регистры YMM или ZMM.
(Но если бы были ложные зависимости, movaps xmm0, [rdi]
в цикле, возможно, пришлось бы ждатьдо тех пор, пока последняя инструкция для записи xmm0
в предыдущей итерации не будет завершена. Это лишит KNL возможности выполнять не по порядку выполнение, чтобы перекрывать независимую работу между циклами итераций и скрывать нагрузку + задержка FP.)
Существует также возможность декодирования остановок на KNL при запуске устаревших инструкций SSE / SSE2: он останавливается на инструкциях с более чем 3 префиксами, включая 0F
экранирующих байтов.Так, например, любая инструкция SSSE3 или SSE4.x с префиксом REX для доступа к r8..r15 или xmm8..xmm15 вызовет задержку декодирования от 5 до 6 циклов.
Но этого не произойдет, еслиВы пропустили все опции -x
/ -march
, потому что SSE1 / SSE2 + REX все еще в порядке.Просто (опционально REX) + 2 других префикса для таких инструкций, как 66 0F 58 addpd
.
См. Руководство по микроарху Agner Fog в главе KNL: 16.2 извлечение и декодирование инструкций .
OpenMP - если вы смотрите на OpenMP для использования нескольких потоков, очевидно, что KNL имеет гораздо больше ядер.
Но даже в пределах одного физического ядра,KNL имеет 4-х стороннюю гиперпоточность как еще один способ (кроме exec-порядка exec), чтобы скрыть высокую задержку своих инструкций SIMD.Например, задержка FMA / add / sub составляет 6 циклов в KNL против 4 в Skylake / Coffee Lake.
Таким образом, разбиение проблемы на несколько потоков может иногда значительно увеличить использование каждого отдельного ядра в KNL.Но в таком крупномядерном центральном процессоре, как Coffee Lake, его огромные возможности неупорядоченного выполнения уже могут находить и использовать весь параллелизм на уровне команд во многих циклах, даже если тело цикла выполняет цепочку действий с каждым независимым входом..