Допустим, у нас есть процессор с двумя ядрами (C0 и C1) и строка кэша, начинающаяся с адреса k
, которая изначально принадлежит C0. Если C1 выдает команду сохранения в 8-байтовом слоте в строке k
, повлияет ли это на пропускную способность следующих инструкций, которые выполняются на C1?
В руководстве по оптимизации Intel есть следующий параграф
Когда инструкция записывает данные в ячейку памяти [...], процессор гарантирует, что у него есть строка, содержащая это место в памяти. находится в его кэше L1d [...]. Если строка кэша отсутствует, выполняется выборка со следующих уровней с помощью запроса RFO [...] RFO, и сохранение данных происходит после удаления инструкции. Таким образом, задержка хранилища обычно не влияет на саму инструкцию хранилища.
Со ссылкой на следующий код:
// core c0
foo();
line(k)->at(i)->store(kConstant, std::memory_order_release);
bar();
baz();
Цитата из руководства Intel заставляет меня предположить, что в код выше, выполнение кода будет выглядеть так, как если бы хранилище было по существу бездействующим, и не повлияло бы на задержку между концом foo()
и началом bar()
. Напротив, для следующего кода
// core c0
foo();
bar(line(k)->at(i)->load(std::memory_order_acquire));
baz();
Задержка между концом foo()
и началом bar()
будет зависеть от нагрузки, так как следующий код имеет результат загрузки как зависимость.
Этот вопрос в основном касается того, как процессоры Intel (в семействе Broadwell или новее) работают в приведенном выше случае. Кроме того, в частности, как код C ++, который выглядит так, как показано выше, компилируется до сборки для этих процессоров.