Используются ли буферы объединения записи для обычной записи в области памяти WB на Intel?

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

Например, в Справочном руководстве по оптимизации архитектур Intel 64 и IA-32 раздел "3.6.10 Комбинирование записи" начинается со следующего описания (выделение добавлено):

Комбинирование записи (WC) улучшает производительность двумя способами:

• В случае пропуска записи в кэш первого уровня это позволяет нескольким хранилищам в одной и той же строке кэша произойти до того, как эта строка кэша будет считана для владения (RFO) из дальнейшего положения в иерархии кеш / память. Затем читается остальная часть строки, и байты, которые не были записаны, объединяются с неизмененными байтами в возвращенной строке.

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

Существует шесть буферов объединения записи (на процессорах Pentium 4 и Intel Xeon с сигнатурой CPUID семейства кодирования 15, кодировка модели 3; имеется 8 буферов объединения записи). Два из этих буферов могут быть записаны на более высокие уровни кэша и освобождены для использования при других ошибках записи. Только четыре буфера объединения записи гарантированно будут доступны для одновременного использования. Комбинирование записи применяется к типу памяти WC; это не относится к типу памяти UC.

В каждом процессорном ядре процессоров Intel Core Duo и Intel Core Solo имеется шесть буферов записи. Процессоры на основе микроархитектуры Intel Core имеют восемь буферов для записи в каждом ядре. Начиная с микроархитектуры Intel под кодовым именем Nehalem, для объединения с записью доступно 10 буферов.

Комбинированные буферы записи используются для хранилищ всех типов памяти. Они особенно важны для записи в некэшированную память...

Мой вопрос заключается в том, применимо ли комбинирование записи к областям памяти WB (это "нормальная" память, которую вы используете в пользовательских программах в 99,99% времени), когда используете обычные хранилища (это что-то кроме не временных хранилищ, то есть хранилищ, которые вы используют 99,99% времени).

Текст выше трудно точно интерпретировать, и, поскольку он не обновлялся со времен Core Duo. У вас есть часть, которая говорит, что расчесывание записи "применимо к памяти WC, но не к UC", но, конечно, не учитывает все другие типы, такие как WB. Позже вы увидите, что "[WC] особенно важен для записи в не кэшированную память", что явно противоречит "не относится к части UC".

Так используются ли буферы объединения записи на современных чипах Intel для обычных хранилищ в памяти WB?

1 ответ

Да, свойства объединения и объединения записей LFB поддерживают все типы памяти, кроме типа UC. Вы можете наблюдать их влияние экспериментально, используя следующую программу. Он принимает два параметра в качестве входных данных:

  • STORE_COUNT: количество 8-байтовых хранилищ для последовательного выполнения.
  • INCREMENT: шаг между последовательными магазинами.

Есть 4 разных значения INCREMENT что особенно интересно:

  • 64: Все хранилища выполняются на уникальных строках кэша. Объединение и объединение записей не будут иметь эффекта.
  • 0: все хранилища находятся в одной и той же строке кэша и в одном и том же месте в этой строке. Запись слияния вступает в силу в этом случае.
  • 8: Каждые 8 ​​последовательных хранилищ находятся в одной и той же строке кэша, но в разных местах в этой строке. Комбинация записи вступает в силу в этом случае.
  • 4: целевые местоположения последовательных хранилищ перекрываются в одной и той же строке кэша. Некоторые магазины могут пересекать две строки кэша (в зависимости от STORE_COUNT). И объединение записи и объединение будут иметь эффект.

Есть еще один параметр, ITERATIONS, который используется для повторения одного и того же эксперимента много раз, чтобы сделать надежные измерения. Вы можете держать его на 1000.

%define ITERATIONS 1000

BITS 64
DEFAULT REL

section .bss
align 64
bufsrc:     resb STORE_COUNT*64

section .text
global _start
_start:  
    mov ecx, ITERATIONS

.loop:
; Flush all the cache lines to make sure that it takes a substantial amount of time to fetch them.
    lea rsi, [bufsrc]
    mov edx, STORE_COUNT
.flush:
    clflush [rsi]
    sfence
    lfence
    add rsi, 64
    sub edx, 1
    jnz .flush

; This is the main loop where the stores are issued sequentially.
    lea rsi, [bufsrc]
    mov edx, STORE_COUNT
.inner:
    mov [rsi], rdx
    sfence ; Prevents potential combining in the store buffer.
    add rsi, INCREMENT
    sub edx, 1
    jnz .inner

; Spend sometime doing nothing so that all the LFBs become free for the next iteration.
    mov edx, 100000
.wait:
    lfence
    sub edx, 1
    jnz .wait

    sub ecx, 1
    jnz .loop

; Exit.    
    xor edi,edi
    mov eax,231
    syscall

Я рекомендую следующую настройку:

  • Отключите все аппаратные средства предварительной выборки, используя sudo wrmsr -a 0x1A4 0xf, Это гарантирует, что они не будут мешать (или иметь минимальное вмешательство) в экспериментах.
  • Установите частоту процессора на максимум. Это увеличивает вероятность того, что основной цикл будет полностью выполнен до того, как первая строка кэша достигнет L1, и приведет к освобождению LFB.
  • Отключите гиперпоточность, потому что LFB являются общими (по крайней мере со времен Sandy Bridge, но не на всех микроархитектурах).

L1D_PEND_MISS.FB_FULL Счетчик производительности позволяет нам фиксировать эффект объединения записей в отношении того, как он влияет на доступность LFB. Это поддерживается на Intel Core и позже. Это описано следующим образом:

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

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

На следующем рисунке приведены графики STORE_COUNT против общего L1D_PEND_MISS.FB_FULL деленное на ITERATIONS,

введите описание изображения здесь

Мы можем наблюдать следующее:

  • Понятно, что есть ровно 10 LFB.
  • Когда возможно объединение или объединение записи, L1D_PEND_MISS.FB_FULL ноль для любого количества магазинов.
  • Когда шаг составляет 64 байта, L1D_PEND_MISS.FB_FULL больше нуля, когда количество магазинов больше 10.

Позже вы увидите, что "[WC] особенно важен для записи в не кэшированную память", что явно противоречит "не относится к части UC".

Как WC, так и UC классифицируются как uncachable. Таким образом, вы можете соединить два оператора, чтобы сделать вывод, что WC особенно важен для записи в память WC.

Смотрите также: Где находится объединяющий запись буфер? х86

Другие вопросы по тегам