Можно ли для работы XMM/YMM FP на Intel Haswell использовать FMA вместо ADD?

Этот вопрос предназначен для упакованных плавающих операций с одиночной записью с регистрами XMM/YMM в Haswell.

Итак, согласно потрясающей, потрясающей таблице составленный Агнером Фогом, я знаю, что MUL может выполняться как на портах p0, так и на p1 (с пропускной способностью recp 0,5), в то время как только ADD выполняется только на порту p1 (с пропускной способностью recp 1). Я могу исключить это ограничение, НО я также знаю, что FMA может выполняться либо на порту p0, либо на порту p1 (с пропускной способностью 0,5). Поэтому меня смущает, почему простой ADD будет ограничен только p1, когда FMA может использовать либо p0, либо p1, и он выполняет как ADD, так и MUL. Я неправильно понимаю таблицу? Или кто-нибудь может объяснить, почему так?

То есть, если я правильно понял, почему бы Intel просто не использовать операцию FMA в качестве основы как для простого MUL, так и для простого ADD, тем самым увеличив пропускную способность как для ADD, так и для MUL. В качестве альтернативы, что помешает мне использовать две одновременные независимые операции FMA для эмуляции двух одновременных независимых операций ADD? Какие штрафы связаны с выполнением ADD-by-FMA? Очевидно, что используется большее количество регистров (2 регистра для ADD против 3 регистров для ADD-by-FMA), но кроме этого?


person codechimp    schedule 04.03.2015    source источник
comment
Чистое предположение: FPU на порту 0 для Haswell может обрабатывать только 5-тактовые инструкции. У него нет логики раннего выхода, которая позволяет ему обрабатывать как 3-, так и 5-тактовые инструкции. FP-add — это 3-тактовая инструкция, поэтому она не может войти в порт-0.   -  person Mysticial    schedule 04.03.2015
comment
Как давно назревшее обновление: Intel в конечном итоге использовала FMA и для ADD, то есть на Skylake. Skylake уменьшает задержку FMA до 4 тактов. Этого оказалось достаточно, чтобы они отказались от выделенного 3-тактного FP-ADD и вставили его в аппаратное обеспечение 4-тактного FMA. Так что теперь у нас есть и FP-ADD двойного выпуска.   -  person Mysticial    schedule 30.06.2017


Ответы (1)


Вы не единственный, кто не понимает, почему Intel это сделала. Агнер Фог в своем руководстве по микроархитектуре пишет для Haswell:

Странно, что есть только один порт для сложения с плавающей запятой, но два порта для умножения с плавающей запятой.

На доске объявлений Агнер он также пишет

Есть два исполнительных модуля для умножения с плавающей запятой и для объединенного умножения и сложения, но только один исполнительный модуль для сложения с плавающей запятой. Этот дизайн кажется неоптимальным, поскольку код с плавающей запятой обычно содержит больше сложений, чем умножений.

Эта ветка продолжается с дополнительной информацией по этому вопросу, которую я предлагаю вам прочитать, но я не буду цитировать здесь.

Он также обсуждает это в этом ответе здесь за цикл для песчаного моста и хасвелла-sse2-avx-avx2

Задержка инструкций FMA на Haswell составляет 5, а пропускная способность — 2 за такт. Это означает, что вы должны поддерживать 10 параллельных операций, чтобы получить максимальную пропускную способность. Если, например, вы хотите добавить очень длинный список f.p. чисел, вам пришлось бы разделить его на десять частей и использовать десять регистров-аккумуляторов.

Это действительно возможно, но кто будет делать такую ​​странную оптимизацию для одного конкретного процессора?

Его ответ там в основном отвечает на ваш вопрос. Вы можете использовать FMA, чтобы удвоить пропускную способность добавления. На самом деле я делаю это в своих тестах пропускной способности для сложения и действительно вижу, что оно удваивается.

Таким образом, для добавления, если ваш расчет связан с задержкой, не используйте FMA, используйте ADD. Но если пропускная способность ограничена, вы можете попробовать использовать FMA (установив множитель на 1,0), но вам, вероятно, придется использовать много регистров AVX для этого.

Я развернул 10 раз, чтобы получить максимальную пропускную способность здесь 21600232">развертывание цикла для достижения максимальной пропускной способности с помощью ivy-bridge-and-haswell

person Z boson    schedule 05.03.2015
comment
кто бы сделал такую ​​странную оптимизацию под один конкретный процессор? - Prime95 делает это. И я сделал это, а также. Это совсем не сложно, когда все ваши встроенные функции проходят через пользовательские макросы. - person Mysticial; 05.03.2015
comment
@Mysticial, да, я сделал это и для своих тестов пропускной способности. Но я еще не сделал этого ни для чего полезного. Я думаю, для моего кода GEMM, но я все равно уже развернул 8x, и переход с 8x на 10x почти не имеет значения. - person Z boson; 05.03.2015
comment
Спасибо за ответ. Я не видел комментария Агнера по этому вопросу. Я только изучал его таблицу. Посмотрю другие его записи. Я понимаю точку зрения о задержке/компромиссе, хотя я все еще изучаю изящное искусство управления ими. В чем я больше не был уверен, так это в том, будет ли какой-то неинтуитивный конфликт портов или ошибка точности. - person codechimp; 05.03.2015
comment
@Z boson, спасибо за ссылку на развертывание цикла. Но я уже нашел его вчера, до загрузки этого вопроса, и уже добавил его в закладки для изучения. Интуитивно я понимаю ценность развертывания, но технические детали управления задержкой и пропускной способностью мне пока не так понятны. - person codechimp; 05.03.2015