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

Несколько лет назад я изучал ассемблер x86, конвейерную обработку ЦП, промахи в кеше, предсказание ветвлений и все такое прочее.

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

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

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

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

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

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


person spraff    schedule 30.08.2011    source источник
comment
Тенденция к длинному конвейеру ЦП изменилась, когда мы вступили в эру маломощных систем. -хочешь узнать, как решается проблема в процессорах Atom или вообще настольных процессорах (core2 / i7 / k10)?   -  person osgx    schedule 13.09.2011
comment
Я имел в виду Atom и аналогичные процессоры с этой линейкой, я полагаю, что мобильные процессоры имеют разные профили производительности по сравнению с. косвенные инструкции, но демонстрация того, о чем этот вопрос.   -  person spraff    schedule 13.09.2011


Ответы (1)


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

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

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

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

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

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

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

Косвенный предиктор ветвления

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

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

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

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

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

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

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

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

Для Атомов от agner's micro:

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

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

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

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

person osgx    schedule 31.08.2011