Используются ли буферы объединения записи для обычной записи в области памяти 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