Каково минимальное количество цепочек зависимостей, чтобы максимизировать производительность?

Данная цепочка инструкций связана истинными зависимостями и периодически повторяется (то есть цикл), например (a->b->c)->(a->b->c)->...

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

  • (A0-> b0-> c0) -> (a0-> b0-> c0) ->...
  • (A1->b1->c1)->(a1->b1->c1)->...

Механизм неупорядоченности планирует каждую инструкцию для соответствующего модуля ЦП, который имеет задержку и обратную пропускную способность.

Какое оптимальное количество цепочек зависимостей максимизирует производительность?

Согласно руководству Агнера " Оптимизация подпрограмм на языке ассемблера", раздел 12.15: "Оптимальным числом аккумуляторов, если ЦПУ больше нечего делать, является задержка самой критической команды в цепочке зависимостей, деленная на обратную пропускную способность для этой команды". Что означает "самая важная инструкция"? Есть ли какая-либо другая техническая документация для решения этой проблемы?

1 ответ

Решение

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

Это также зависит от того, насколько широко оборудование. например

  • PIII с двумя исполнительными блоками ALU и 3 на тактовую частоту UOP
  • Haswell с четырьмя исполнительными блоками ALU (только три из которых могут обрабатывать векторы) и по 4 на тактовую пропускную способность в слитых областях.

Я думаю, что "самая важная инструкция" означает ту, которая составляет большую часть длины критического пути. Если цепочка зависимостей, переносимая циклами, состоит из нескольких инструкций с разными задержками, это своего рода среднее значение. (Как может быть среднее геометрическое?)


Хорошим примером является добавление FP (например, суммирование массива):

На Sandybridge он имеет пропускную способность по одному на такт, но задержку составляет 3 с, поэтому единую цепочку зависимых addps инструкции выполняются со скоростью 1 моп на 3с, поддерживая только 1/3 от максимальной пропускной способности умножения FP. (И оставляя два других исполнительных порта полностью незанятыми.)

Три параллельных деп-цепочки могут поддерживать порт1 насыщенным addps инструкции. Так что, если вы используете три аккумулятора, вы можете оставить три прибавки в полете. Если вы также сохраняете 5 множителей FP в полете, вы также можете насыщать port0. Служебные циклы могут выполняться на порту 5 (и, надеюсь, не перехватывать циклы с p01). Загрузочные мопы могут сливаться с надстройками, поэтому они не занимают полосу пропускания слитых доменов. Но вы могли бы сделать некоторые нагрузки с отдельным movaps инструкции и до сих пор не насыщают пропускную способность UOP с 4-мя тактовыми модулями, но узкие места во внешнем интерфейсе могут ограничить пропускную способность.


У Haswell по-прежнему есть только одна пропускная способность для тактовой частоты для добавления FP, но по две на тактовую частоту для FP mul и FMA.

Поэтому, если вы суммируете массив с использованием FMA (с множителем 1,0), вам понадобится 10 векторных аккумуляторов (10 цепочек деп), чтобы удерживать 10 FMA в полете, насыщая p01. p5 и p6 остаются неиспользованными, но вы также можете насыщать порты нагрузки микроплавкими нагрузками.


Skylake уменьшил задержку FMA на 1 такт, до 4, и сбросил единицу добавления FP. (Таким образом, добавление FP выполняется в блоке FMA, который удвоил пропускную способность для [v]addps, стоимостью в 1с больше латентности).

Так что на SKL вам нужно всего 8 векторных аккумуляторов (8 цепочек деп) для насыщения p01. Но наличие большего числа цепочек депов не повредит, пока у вас не закончатся регистры. Так что код, который идеально подходит для Haswell с использованием 10 аккумуляторов, все равно должен быть идеальным для SKL. Вы можете сэкономить немного энергии, просто используя addps вместо fma213ps (или что-то еще) с постоянным вектором 1,0, хотя.


Посмотрите таблицы инструкций Агнера для пропускной способности / задержки / номера портов, и его микроархив PDF для получения дополнительной информации. Я не проверял номера портов или номера задержек, но я набрал этот пример так часто, что уверен, что он правильный:P.

Также смотрите другие ссылки в теге x86 вики.

Другие вопросы по тегам