Что означает “невременной” доступ к памяти в x86

StackOverflow https://stackoverflow.com/questions/37070

  •  09-06-2019
  •  | 
  •  

Вопрос

Это несколько низкоуровневый вопрос.В сборке x86 есть две инструкции SSE:

MOVDQA xmmi, m128

и

MOVNTDQA xmmi, m128

В Руководстве разработчика программного обеспечения IA-32 говорится, что NT в MOVNTDQA расшифровывается как Вневременной, и что в остальном это то же самое, что MOVDQA.

Мой вопрос в том, что делает Вневременной в смысле?

Это было полезно?

Решение

Временные инструкции SSE (MOVNTI, MOVNTQ и т. д.) не соответствуют нормальным правилам когерентности кэша. Поэтому за временными хранилищами должна следовать инструкция SFENCE, чтобы другие процессоры своевременно видели их результаты.

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

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

Источник: http://lwn.net/Articles/255364/

Другие советы

Эспо сильно бьет по воротам. Просто хотел добавить мои два цента:

«Невременный» Фраза означает отсутствие временной локализации. Кэши используют два вида локальности - пространственную и временную, и, используя невременную инструкцию, вы сигнализируете процессору, что не ожидаете, что элемент данных будет использован в ближайшем будущем.

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

Согласно Руководству разработчика программного обеспечения для архитектур Intel® 64 и IA-32, том 1:Базовая архитектура, Глава "Программирование с использованием расширений Intel Streaming SIMD (Intel SSE)":

Кэширование временных данных по сравнениюНестационарные данные

Данные, на которые ссылается программа, могут быть временными (данные будут использоваться повторно) или нестационарными (на данные будут ссылаться один раз и не будут использоваться повторно в ближайшем будущем).Например, программный код обычно является временным, тогда как мультимедийные данные, такие как список отображения в трехмерном графическом приложении, часто не являются временными.Чтобы эффективно использовать кэши процессора, обычно желательно кэшировать временные данные, а не кэшировать нестационарные данные.Перегрузку кэшей процессора нестационарными данными иногда называют "загрязнением кэшей".Инструкции управления кэшируемостью SSE и SSE2 позволяют программе записывать нестационарные данные в память способом, который сводит к минимуму загрязнение кэшей.

Описание временных инструкций по загрузке и хранению.Источник:Руководство разработчика программного обеспечения для архитектур Intel 64 и IA-32, том 2:Ссылка На набор инструкций

ЗАГРУЗИТЬ (MOVNTDQA—Загрузить подсказку с двойным четырехсловием, не выровненным по времени)

Загружает двойное четырехсловие из исходного операнда (второго операнда) в конечный операнд (первый операнд), используя нестационарную подсказку, если источником памяти является тип памяти WC (объединение записи) [...]

[...] процессор не считывает данные в иерархию кэша и не извлекает соответствующую строку кэша из памяти в иерархию кэша.

Обратите внимание, что, как комментирует Питер Кордес, это бесполезно в обычной памяти WB (с обратной записью) на текущих процессорах, потому что подсказка NT игнорируется (вероятно, потому, что нет NT-поддерживающих HW предвыборщиков) и применяется полная семантика строго упорядоченной загрузки. prefetchnta может использоваться в качестве уменьшающей загрязнение нагрузки из памяти WB

ХРАНИТЬ (MOVNTDQ—Хранить упакованные целые числа, используя нестационарную подсказку)

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

[...] процессор не записывает данные в иерархию кэша и не извлекает соответствующую строку кэша из памяти в иерархию кэша.

Используя терминологию, определенную в Политики записи в кэш и производительность, их можно рассматривать как обходные для записи (no-write-allocate, no-fetch-on-write-miss).

Наконец, это может быть интересно рассмотреть Заметки Джона Макэлпина о временных хранилищах.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top