Следующие эксперименты показывают, что мопы освобождаются в какой-то момент до завершения загрузки. Хотя это не полный ответ на ваш вопрос, он может дать некоторые интересные идеи.
На Skylake есть станция резервирования на 33 места для загрузки (см. { ссылка }). Это также относится и к Coffee Lake i7-8700K, который используется для следующих экспериментов.
Мы предполагаем, что R14
содержит действительный адрес памяти.
clflush [R14]
clflush [R14+512]
mfence
# start measuring cycles
mov RAX, [R14]
mov RAX, [R14]
...
mov RAX, [R14]
mov RBX, [R14+512]
# stop measuring cycles
mov RAX, [R14]
развернуто 35 раз. Нагрузка из памяти занимает в этой системе не менее 280 циклов. Если загрузка завершится на 33-входной станции резервирования до завершения, последняя загрузка может начаться только после более чем 280 циклов, и потребуется еще ~ 280 циклов. Однако общее измеренное время для этого эксперимента составляет всего около 340 циклов. Это указывает на то, что загрузки мопов покидают RS через некоторое время до завершения.
Напротив, в следующих экспериментах показан случай, когда большинство мопов вынуждены оставаться в резервировании до завершения первой загрузки:
mov RAX, R14
mov [RAX], RAX
clflush [R14]
clflush [R14+512]
mfence
# start measuring cycles
mov RAX, [RAX]
mov RAX, [RAX]
...
mov RAX, [RAX]
mov RBX, [R14+512]
# stop measuring cycles
Первые 35 загрузок теперь имеют зависимости друг от друга. Измеренное время для этого эксперимента составляет около 600 циклов.
Эксперименты проводились с отключенным всем ядром, кроме одного, и с регулятором ЦП, установленным на производительность (cpupower frequency-set --governor performance
).
Вот nanoBench команды, которые я использовал:
./nanoBench.sh -unroll 1 -basic -asm_init "clflush [R14]; clflush [R14+512]; mfence" -asm "mov RAX, [R14]; mov RAX, [R14]; mov RAX, [R14]; mov RAX, [R14]; mov RAX, [R14]; mov RAX, [R14]; mov RAX, [R14]; mov RAX, [R14]; mov RAX, [R14]; mov RAX, [R14]; mov RAX, [R14]; mov RAX, [R14]; mov RAX, [R14]; mov RAX, [R14]; mov RAX, [R14]; mov RAX, [R14]; mov RAX, [R14]; mov RAX, [R14]; mov RAX, [R14]; mov RAX, [R14]; mov RAX, [R14]; mov RAX, [R14]; mov RAX, [R14]; mov RAX, [R14]; mov RAX, [R14]; mov RAX, [R14]; mov RAX, [R14]; mov RAX, [R14]; mov RAX, [R14]; mov RAX, [R14]; mov RAX, [R14]; mov RAX, [R14]; mov RAX, [R14]; mov RAX, [R14]; mov RAX, [R14]; mov RBX, [R14+512]"
./nanoBench.sh -unroll 1 -basic -asm_init "mov RAX, R14; mov [RAX], RAX; clflush [R14]; clflush [R14+512]; mfence" -asm "mov RAX, [RAX]; mov RAX, [RAX]; mov RAX, [RAX]; mov RAX, [RAX]; mov RAX, [RAX]; mov RAX, [RAX]; mov RAX, [RAX]; mov RAX, [RAX]; mov RAX, [RAX]; mov RAX, [RAX]; mov RAX, [RAX]; mov RAX, [RAX]; mov RAX, [RAX]; mov RAX, [RAX]; mov RAX, [RAX]; mov RAX, [RAX]; mov RAX, [RAX]; mov RAX, [RAX]; mov RAX, [RAX]; mov RAX, [RAX]; mov RAX, [RAX]; mov RAX, [RAX]; mov RAX, [RAX]; mov RAX, [RAX]; mov RAX, [RAX]; mov RAX, [RAX]; mov RAX, [RAX]; mov RAX, [RAX]; mov RAX, [RAX]; mov RAX, [RAX]; mov RAX, [RAX]; mov RAX, [RAX]; mov RAX, [RAX]; mov RAX, [RAX]; mov RAX, [RAX]; mov RBX, [R14+512]"