
В популярных публикациях много слов о «глубоком обучении», причем, с появлением каждого нового функционального расширения, формулировки повторяются снова и снова. Видимо, каждый раз обучение становится еще более глубоким. Между тем, обратившись к документации (и позвав на помощь эмулятор Intel SDE), нетрудно убедиться, что составными частями для реализации технологий со столь замысловатыми названиями являются операции линейной алгебры: последовательности умножений и сложений.
С целью оптимизации машинного кода, необходимого для реализации алгоритмов линейной алгебры, в частности, — обработки векторов и матриц, разработано семейство функциональных расширений FMA (Fused Multiply and Add). Именно их применение позволяет комбинировать в одной процессорной инструкции арифметические действия умножения и сложения. Заметим, что FMA инструкции оперируют числами с плавающей точкой, в то время как функциональное расширение VNNI (Vector Neural Network Instructions) используется для обработки целочисленных операндов.
Блок-схема выполнения векторной операции Fused Multiply and Add
Дополнительным плюсом FMA является улучшение точности вычислений, поскольку при выполнении нескольких последовательных арифметических операций одной инструкцией округлению подвергается только окончательный результат, в то время как при использовании умножений и сложений отдельными инструкциями, потеря точности имеет место после каждого действия.
В чем отличие FMA и FMA4
Рассмотрим выражение, вычисление которого достаточно типично для операций линейной алгебры:
Y = X1 * X2 + X3
В трехоперандном варианте (FMA, синоним FMA3 instructions), регистр-получатель результата Y всегда совпадает с одним из трех операндов-источников X1, X2, X3. Поэтому нельзя выполнить операцию, сохранив все регистры-аргументы неизменными — один из них будет использован для формирования результата и его исходное значение будет потеряно.
Четырехоперандный вариант (FMA4 instructions) рассчитан на использование четырех независимых операндов, что позволяет сохранить в неприкосновенности содержимое всех аргументов.
Экспериментаторам на заметку
Мнение, согласно которому четырехоперандные FMA-инструкции являются непозволительной роскошью, как правило, ассоциируют с политикой Intel, «репрессировавшей» FMA4-формат. По другой версии, причиной блокировки является ошибка в дизайне FMA-блока процессоров Ryzen. Вместе с тем, источник заявляет о недокументированной поддержке и перспективах возрождения (уже в документированном виде) FMA4 в процессорах AMD.
Под недокументированной поддержкой в этом контексте понимается ситуация, при которой CPUID-бит, указывающий на поддержку FMA4, обнулен, но попытка использовать инструкции FMA4 вместо предусмотренной в таком «аварийном» случае генерации исключения по недопустимому коду операции приводит к нормальному ее выполнению.
Экспериментаторы, желающие самостоятельно проверить такой сценарий, должны предусмотреть обработку возможных исключений, чтобы избежать аварийного завершения приложения. Кроме того, в силу деликатности ситуации, до обретения FMA4-инструкциями официального статуса, нет гарантии, что результат выполнения окажется корректным.
О документированных возможностях
Выполним несколько простых проверок, опираясь исключительно на документированную функциональность процессора AMD EPYC 7351 16-Core Processor.
Расширение FMA, в «классической» трехоперандной форме, официально поддерживается процессором AMD EPYC 7351 16-Core Processor, о чем свидетельствует CPUID функция 00000001h, регистр ECX, бит 12
Расширение FMA, в «продвинутой» четырехоперандной форме, официально не поддерживается процессором AMD EPYC 7351 16-Core Processor, о чем свидетельствует CPUID функция 80000001h, регистр ECX, бит 16
«Легальные» результаты выполнения инструкции CPUID неожиданностей не принесли: FMA поддерживается, FMA4 — нет. Оценим производительность инструкций FMA.
Цикл вычисления скалярного произведения векторов, по оси X откладывается размер каждого из двух перемножаемых векторов в байтах, по оси Y — производительность в гигабайтах в секунду (около 45.6), исследование в окрестности X = объем кэш-памяти данных L1, работает один поток
В FMA-тесте утилиты NCRB вычисляется скалярное произведение двух векторов, поэтому адресуется два читаемых массива, размер которых в байтах отложен по X. Тест использует формат двойной точности (double precision), одно число занимает 8 байт (64 бита) это необходимо учитывать при пересчете результата в GFLOPS. Одна векторная 256-битная операция обрабатывает 256 / 64 = 4 операнда. Ввиду наличия двух массивов, теоретический момент переполнения L1 должен иметь место при
X = 32 KB / 2 = 16 KB
При использовании SMT кэш-память каждого ядра обслуживает два потока, поэтому теоретический момент переполнения L1 еще в два раза ниже
X = 16 KB / 2 = 8 KB
Напомним, размер кэш-памяти данных первого уровня процессора AMD EPYC 7351 составляет 32 килобайта.
Время выполнения операции определяется двумя составляющими, первая из которых зависит от времени доставки данных из кэш-памяти, а вторая — не зависит.
- Чтение элементов перемножаемых векторов из кэш-памяти в операционный блок.
- Вычисления: операции умножения и сложения и манипуляции с данными внутри операционного блока.
Цикл вычисления скалярного произведения векторовб по оси X откладывается размер каждого из двух перемножаемых векторов в байтах, по оси Y — производительность в гигабайтах в секунду (около 733.9), исследование в окрестности X = объем кэш-памяти данных L1; работает 32 потока
Выводы
Начав исследование с документированной формы FMA, мы обнаружили неплохой уровень масштабирования производительности. При условии размещения обрабатываемых массивов в кэш-памяти данных первого уровня, соотношение производительности двух вариантов: с использованием одного логического процессора и всех 32 логических процессоров составляет 45.6 к 733.9 что весьма близко к 16. А это, напомним, количество ядер исследуемого процессора.