2017-01-07 23 views
4

Я пытаюсь понять, как можно максимизировать количество операций, которые я могу получить на своем CPU. Я делаю простую программу умножения матрицы, и у меня есть процессор Skylake. Я смотрел на страницу википедии для информации о флопе об этой архитектуре, и у меня есть знания, которые это понимают.Понимание производительности команд FMA

С моей точки зрения, инструкции FMA позволяют входить в 3-х ходовые входы FP? И позвольте смешивать между добавлениями и умножениями между ними. Но что происходит, когда я добавляю только два поплавка? Он просто умножает его на единицу? Могу ли я добавить 3 поплавки за 1 цикл, или это будет разделено? Я видел, что у Skylake есть 32 FLOPs/cycle для одноточечных входов, но в чем смысл «две 8-х сторонние инструкции FMA»?

Заранее спасибо за объяснения

+1

Этот вопрос становится более интересным, если вы сравните Haswell и Skylake. Haswell может использовать только один добавочный AVX за такт, но две операции FMA за такт. Это означает, что вы можете удвоить свою пропускную способность путем использования двух операций FMA, умноженных на 1.0. OTH, латентность для FMA равна 5, тогда как добавление три на Haswell, поэтому вам нужно использовать 10 параллельных аккумуляторов, чтобы получить максимальную пропускную способность с FMA, тогда как вам нужно только 3 с добавлением. В дополнение к Skylake и FMA есть такая же латентность и пропускная способность, поэтому нет причин использовать FMA для добавления. –

ответ

5

FMA вычисляет ± а * Ь ± с в одной операции, с одной ошибки округления. Вот что он делает, больше ничего. Вычисление a + b + c не может быть выполнено с помощью инструкции FMA; для этого вам нужны две зависимые операции ADD.

В зависимости от компилятора вам может потребоваться включить параметр компилятора, чтобы разрешить использование инструкций FMA, поскольку они не дают результатов, идентичных умножению, за которым следует добавление. Возможно, вам придется перестроить код в некоторых случаях, например, b + c d + e будет рассчитываться как x = a b; y = FMA (c, d, x), z = y + e, но e + a b + c * d будет рассчитываться как x = FMA (a, b, e); z = FMA (c, d, x). Базовый расчет операции БПФ может выполняться с помощью восьми операций с плавающей запятой и может быть переписан в виде 10 операций с использованием четырех FMA и двух других операций.

«Две 8-сторонние инструкции FMA» означает, что он может выполнять инструкции FMA с двумя 256-битовыми векторными регистрами, содержащими по 8 поплавков, и два из них в одном цикле.

+0

Очень четкое объяснение. Спасибо: D –

+0

Один из способов дать понять компилятору, что использовать написанную команду с объединенной добавочной сборкой можно использовать функции 'fma',' fmaf', 'fmal' в исходном коде, но тогда if компилятор настроен на создание обратного совместимого кода и для учета разницы между fma и "' * ', за которыми следует' + '", эти функции будут скомпилированы как дорогие последовательности многих инструкций, например https://sourceware.org /bugzilla/attachment.cgi?id=6017 или как https://sourceware.org/ml/libc-hacker/2010-10/msg00005.html –

+0

Было бы замечательно, если бы существовал быстрый режим одиночного округления 'a + b + c' инструкция. Это обеспечит быструю добавку «double-double», которая в настоящее время намного медленнее, чем «двойное двойное» умножение с FMA. http://stackoverflow.com/a/30643684/2542702 –