Подтвердить что ты не робот

Как эволюция архитектуры ЦП повлияла на производительность вызовов функциональных функций?

Несколько лет назад я изучал ассемблер x86, конвейер процессора, пропуски кэша, предсказание ветвей и весь этот джаз.

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

Недостатком было то, что любое отклонение нормы было чрезвычайно дорогостоящим. Например, IIRC для некоторых процессоров AMD в эпоху раннего гигагерца был 40 циклов каждый раз, когда вы вызывали функцию через указатель (!), И это было, по-видимому, нормальным.

Это не пренебрежимо малое число "не беспокойтесь об этом"! Имейте в виду, что "хороший дизайн" обычно означает "как можно больший фактор" и "кодировать семантику в типы данных", которые часто подразумевают виртуальные интерфейсы.

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

Я понимаю, что тенденция длинного CPU-конвейера изменилась, когда мы вступаем в эпоху малой мощности. Вот мой вопрос:

Поддерживает ли последнее поколение x86-совместимых процессоров массивные штрафы за вызовы виртуальных функций, предсказания плохих ветвей и т.д.

4b9b3361

Ответ 1

Процессор AMD в раннем гигагерце эпохи имел штраф в 40 циклов каждый раз, когда вы вызывали функцию

Да.. так большой..

Существует метод "Косвенное предсказание ветвей", который помогает предсказать скачок виртуальной функции, если бы какой-то косвенный переход произошел некоторое время назад. По-прежнему существует наказание за первый и неверный прогноз. прыжок функции.

Поддержка варьируется от простого "прогнозируемого права тогда и только тогда, когда предыдущая косвенная ветвь была точно такой же" до очень сложных двухуровневых десятков или сотен записей с обнаружением периодического чередования 2-3 целевых адресов для одной непрямой команды jmp.

Здесь было много эволюции...

http://arstechnica.com/hardware/news/2006/04/core.ars/7

впервые представлен с предиктором непрямой ветки Pentium M:...

Прогнозирование непрямой ветки

Поскольку косвенные ветки загружают свои целевые объекты из реестра, вместо того, чтобы иметь их сразу же доступными, как в случае с прямыми ветвями, их, как известно, трудно предсказать. Прогнозирование основной непрямой ветки - это таблица, в которой хранится информация о предыстории предпочтительных целевых адресов каждой непрямой ветки, с которой сталкивается фронт. Таким образом, когда front-end встречает непрямую ветвь и предсказывает ее как принятую, она может попросить предсказателя непрямой ветки направлять его на адрес в BTB, который, вероятно, понадобится ветке.

http://www.realworldtech.com/page.cfm?ArticleID=rwt051607033728&p=3

Непрямое предсказание ветвлений было впервые введено с микроархитектурой Intels Prescott, а позже и Pentium M.

между 16-50% всех неверных прогнозов отрасли были косвенными (в среднем 29%). Реальная ценность неверного предсказания непрямой ветки для многих новых языков сценариев или высокого уровня, таких как Ruby, Perl или Python, которые используют интерпретаторы. Другие общие непрямые ответвления - это виртуальные функции (используемые в С++) и призывы к указателям на функции.

http://www.realworldtech.com/page.cfm?ArticleID=RWT102808015436&p=5

AMD приняла некоторые из этих уточнений; например, добавление в Барселону и последующие процессоры непрямых ветвящихся предикторов. Однако K8 имеет более старые и менее точные предсказатели ветвления, чем Core 2.

http://www.agner.org/optimize/microarchitecture.pdf

3.12 Косвенные переходы на старых процессорах Косвенные переходы, косвенные вызовы и возвраты могут каждый раз обращаться к другому адресу. метод прогнозирования для косвенного скачка или косвенного вызова, в процессорах старше PM и K10, просто чтобы предсказать, что он перейдет к той же цели, что и в последний раз, когда он был выполнен.

и тот же pdf, стр. 14

Непрямое предсказание скачка Косвенным прыжком или вызовом является инструкция передачи управления, которая имеет более двух возможных цели. Программа С++ может генерировать косвенный переход или вызов с помощью... виртуальной функции. Косвенный прыжок или вызов генерируются в сборке посредством указав регистр или переменную памяти или проиндексированный массив в качестве адресата перехода или инструкции вызова. Многие процессоры делают только одну запись BTB для косвенного перехода или вызова. Это означает, что всегда будет предсказано, что он достигнет той же цели, что и в прошлый раз. Поскольку объектно-ориентированное программирование с полиморфными классами стало более распространенным, растет потребность в прогнозировании косвенных вызовов с несколькими целями. Это можно сделать путем назначения новой записи BTB для каждой новой цели перехода, которая встречается. История буфер и таблица истории шаблонов должны иметь место для более чем одного бита информации для каждый скачок инцидента, чтобы отличить более двух возможных целей. PM - первый процессор x86 для реализации этого метода. Правило прогнозирования на стр. 12 все еще применяется с модификацией того, что теоретический максимальный период, который можно предсказать отлично mn, где m - количество различных целей на косвенный скачок, потому что там mn различные возможные подпоследовательности n-длины. Однако этот теоретический максимум не может достигаются, если он превышает размер таблицы BTB или таблицы истории шаблонов.

Руководство Agner имеет более длинное описание прогноза ветвления во многих современных процессорах и эволюцию предсказателя в процессоре каждого производителя (x86/x86_64).

Также существует множество теоретических методов прогнозирования "косвенных ветвей" (смотрите ученого Google); даже wiki сказал несколько слов об этом http://en.wikipedia.org/wiki/Branch_predictor#Prediction_of_indirect_jumps/

Для атомов из agner micro:

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

Таким образом, для малой мощности прогнозирование непрямой ветки не настолько продвинуто. Так же делает Via Nano:

Предполагается, что косвенные скачки перейдут к той же цели, что и в прошлый раз.

Я думаю, что более короткий трубопровод низкой мощности x86 имеет более низкий штраф, 7-20 тиков.