WC против памяти WB? Другие типы памяти на x86_64?

Не могли бы вы описать значения и различия между WC и WB-памятью на x86_64? Для полноты, пожалуйста, опишите другие типы памяти на x86_64, если они есть.

Ответ 1

Сначала я начну с кэширования обратной записи (WB), так как его легче понять.

Кэширование с обратной записью

Как следует из названия, эта стратегия кэширования пытается отложить запись в системную память как можно дольше.
Идея состоит в том, чтобы использовать только кеш, в идеале.

Однако, поскольку кэш имеет конечный размер, меньший, чем конечный размер памяти, и его внутренняя организация see Wikipedia Cache article for an introduction вводит некоторые противоречивые псевдонимы, иногда необходимо удалить строку кэша в память.
Это событие обратной записи - другим источником событий обратной записи является механизм когерентности кэша see MESI.

Это основная идея ВБ, технически стратегия кэширования определяется действиями, предпринятыми в отношении четырех основных событий.

Event              | Action
-------------------+----------------------------------------------
Read hit           | Read from the cache line
-------------------+----------------------------------------------
Read miss          | Fill the line then read from the cache line
-------------------+----------------------------------------------
Write hit          | Write to the cache line
-------------------+----------------------------------------------
Write miss         | Fill the line then write to the cache line*

* Since P6, we will assume this is always the case

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

Для полноты приведем сравнительную таблицу с другими стратегиями кэширования.
Комбинирование записи (WC) намеренно исключено.

Legend
   LF = Line Fill;         LR = Read from line;   MR = Read from memory
   LW = Write to line;     MW = Write to memory

Event              | WB      |  UC | WT       | WP     |
-------------------+---------+-----+----------+--------+----------
Read hit           | LR      | RM* | LR       | LR     |
-------------------+---------+-----+----------+--------+----------
Read miss          | LF, LR  | RM  | LF, LR   | LF, LR |
-------------------+---------+-----+----------+--------+----------
Write hit          | LW      | WM  | WL, WM** | WM***  |
-------------------+---------+-----+----------+--------+----------
Write miss         | LF, LW  | WM* | WM       | WM     |

* A hit on a UC region can happen if the cache type has been
  changed without invalidating the cache. In truth for UC talking about
  hits is a bit misleading. Caching is bypassed, so it is actually a
  N.A. case.   

** The line can be invalidated as the result of the eviction operation
   used.

*** This can never happen, WP does not use the cache for writes so this
    is actually an N.A. case.  
    Writing directly to memory by bypassing the caches also invalidates
    all the copies of the affected line in other processors.

Примечание. Разница между WP и WT заключается в том, что последний можно рассматривать как "пробивающий" кеши, в то время как первый "обходит" кеши.

Пишем, комбинируя

WC на самом деле не является стратегией кеширования, но, поскольку он тесно связан со стратегиями кеширования, он обсуждается ниже.
Я обнаружил, что Intel SDM довольно запутанны в этом вопросе, такова моя интерпретация этого вопроса.
Исправления приветствуются!

Есть старая бумага от Intel, доступная здесь на WC - ее содержание было включено в раздел 11.3.1 Intel SDM 3, но при этом Intel потеряла некоторый контекст и структуру, которые были доступны в оригинальный документ.

Идея WC заключается в объединении записей до или во время длительной операции, такой как транзакция шины или транзакция когерентности кэша.

Чтобы достичь этого, процессор имеет несколько буферов WC - не путайте их с буфером хранения строк кэша.
Буфер WC - это отдельная сущность!

Количество буферов WC ограничено: в P6 (и, следовательно, в Pentium M) было 6 буферов WC, в Pentium 4 было 8, а с Nehalem было 10 буферов WC see section 3.6.10 of Intel Optimisation manual.

Размер каждого буфера WC не определен архитектурно, но до сих пор он всегда был одинаковым размером строки кэша (поэтому 32 байта для P6, 64 байта для остальных).

Буферы WC сидят перед кэшем.

Теперь поворот WC действительно означает две вещи:

  • Прежде чем ЦПУ будет разрешено выполнять запись в строку кэша, в случае пропуска записи он должен выполнить RFO (чтение для владения), чтобы сообщить другим ЦП, что их кэшированные данные, если таковые имеются, не является недействительным.
    Поскольку это может занять много времени, ЦП паркует хранилище в буфере WC и продолжает свою работу. Подсистема кеша затем будет автономно перемещать буфер WC в соответствующий кеш.
    Если поступает последовательное сохранение в той же строке, для которой выполняется RFO, все они погружаются в буфер WC.

  • Если тип памяти не требует кэширования, то буфер WC действует как стоянка для хранилищ перед их полной передачей на шину.
    Запуск транзакции шины требует некоторых затрат, но после запуска данные могут быть переданы последовательными пакетами (фактически по 8 байт каждый) довольно быстро.
    Запись меньшего количества данных, чем ширина шины памяти, является пустой тратой пропускной способности памяти - почти как если бы шина (настоящая шина, предназначенная для людей) работала наполовину пустой. Таким образом, WC пытается использовать полную ширину шины памяти.

Примечание: Типы памяти UC обходят всю подсистему кэша, включая буфер WC. Тип памяти WC обходит кэши, но не буфер WC.

В первом случае WC позволяет ЦПУ продолжать свою работу, пока выполняется длительная операция, во втором случае он обеспечивает эффективную передачу данных.
В обоих случаях Intel использует один и тот же термин WC, что, по моему мнению, приводит к путанице.
Intel SDM считывает, что WC разрешен только в областях типа памяти WC, но позже заявляет, что он используется для всех типов памяти, и сообщает об этом в описании каждой стратегии кэширования.
Я считаю, что это связано с тем, что Intel ссылается на два WC, описанных выше.
Я полагаю, что второй тип был оригинальным и что буферы WC были повторно использованы, когда MESI стал популярным.


EDIT

Я забыл упомянуть, что тип памяти WC не кешируется (но спекулятивный, предположение было намеренно опущено).
Питер Кордес вкратце изложил это в своем комментарии:

WC - сокращение от USWC: "Некашиваемое спекулятивное объединение при записи".
Ключевым моментом является то, что это не кешируемый тип памяти, поэтому полезны загрузки movntdqa (чтобы загрузить [запись буфера хранения, которая равна ширине полной строки кэша), вместо того, чтобы делать отдельный доступ к DRAM для отдельных загрузок [находится в диапазоне адресов, который может быть кэширован] из той же строки кэша)

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


Только четыре буфера WC могут быть активны в данный момент.
Руководство по оптимизации Intel также сообщает, что только две из них можно использовать для объединения операций записи в кэш.

При использовании WC для объединения хранилищ в память процессор не обеспечивает согласованности.
Буферы WC не отслеживаются, кроме того, между текущими активными буферами WC не выполняется никакой порядок (который распределяется первым).
Когда WC должен быть удален, он выполняется либо одной транзакцией шины, если весь буфер WC загрязнен, либо выполнением до 8 (64/8) или 4 (32/8) транзакций шины, если буфер WC содержит частичные данные..
Опять же, при заполнении буфера WC частичными данными упорядочение между блоками не применяется.

P6 высвобождает буфер WC, как только программное обеспечение записывает вне размера буфера, точный алгоритм определяется реализацией - обычно есть временное окно, позволяющее программному обеспечению объединять записи.
Возможно принудительное выселение путем доступа к области типа памяти UC или при определенных событиях (см. статью, связанную в начале этого раздела).