Инструкция предварительной выборки - PullRequest
19 голосов
/ 26 июня 2010

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

Ответы [ 3 ]

17 голосов
/ 26 июня 2010

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

В некоторых редких случаях, например, при потоковой передаче больших блоков данных, для которых вы выполняете очень мало фактической обработки, вы можете скрыть некоторую задержку с помощью программной предварительной выборки, но очень трудно сделать это правильно - вам нужно начать предварительную выборку за несколько сотен циклов, прежде чем вы собираетесь использовать данные - сделайте это слишком поздно, и вы все равно получите промах кеша, сделайте это слишком рано, и ваши данные могут быть удалены из кэша, прежде чем вы будете готовы его использовать , Часто это ставит предварительную выборку в какую-то несвязанную часть кода, что плохо для модульности и обслуживания программного обеспечения. Что еще хуже, если ваша архитектура изменится (новый ЦП, другая тактовая частота и т. Д.), Так что задержка доступа к DRAM увеличится или уменьшится, вам может потребоваться переместить ваши инструкции предварительной выборки в другую часть кода, чтобы сохранить их эффективность.

В любом случае, если вы чувствуете, что действительно должны использовать предварительную выборку, я рекомендую #ifdefs вокруг любых инструкций предварительной выборки, чтобы вы могли компилировать свой код с предварительной выборкой и без нее и посмотреть, действительно ли она помогает (или мешает) производительности, например,

#ifdef USE_PREFETCH
    // prefetch instruction(s)
#endif

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

4 голосов
/ 02 мая 2012

Даже если учитывать предварительную выборку кода, производительность уже должна быть проблемой.

1: используйте профилировщик кода. Попытка использовать предварительную выборку без профилировщика - пустая трата времени.

2: всякий раз, когда вы найдете инструкцию в критическом месте, которая является аномально медленной, у вас есть кандидатура на предварительную выборку. Часто фактическая проблема заключается в доступе к памяти на линии перед медленной, а не медленной, как указано профилировщиком. Определите, какой доступ к памяти вызывает проблему (не всегда легко), и предварительно выберите ее.

3 Запустите ваш профилировщик снова и посмотрите, будет ли он иметь какое-либо значение. Если это не вынуло это. Иногда я ускорял петли на> 300% таким образом. Как правило, это наиболее эффективно, если у вас есть цикл доступа к памяти не по порядку.

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

1 голос
/ 17 июля 2010

Конечно, вам нужно немного поэкспериментировать, но вам не нужно извлекать циклы (100-300), прежде чем понадобятся данные. Кэш-память второго уровня достаточно велика, так что предварительно выбранные данные могут оставаться там некоторое время.

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

Также для быстрой реализации LL или реализации Tree может быть получено измеримое преимущество, поскольку процессор не знает, что данные нужны в ближайшее время.

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

...