Все ли процессоры, которые формально уважают зависимость, допускают независимые зависимости? - PullRequest
2 голосов
/ 25 мая 2019

Контекст вопроса - обычная кешируемая память, такая как память объектов C и C ++.

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

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

Многие типы процессоров, которые допускают такое поведение, также гарантируют, что, когда значение зависит от результата предыдущей загрузки, все последующие операции, которые зависят от этого значения, происходятВы действительно после нагрузки, в частности нагрузки по адресу, полученному из этого значения.

Но известно, что значение, полученное из другого значения, математически не зависит от параметра;действительно, общая идиома для установки регистра в ноль состоит в том, чтобы фиксировать его значение с самим собой, что синтаксически выводит значение из предыдущего, но семантически не делает.

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

Наиболее очевидные примеры:

  • x ^ x
  • x & 0
  • x | -1
  • x - x
  • x * 0
  • x / x (вызывает исключение, если ноль)

Цель, очевидно, состоит в том, чтобы понять, как компилятор может оптимально поддерживать memory_order_consume в C и C ++ на этих архитектурах, следуя намерениям этой функции (а не вырожденным способом, определяя mo_consume какmo_acquire).

ЗАЯВЛЕНИЕ НА ПРОБЛЕМУ

Проблема заключается в компиляции кода, такого как

r1 = x.load(memory_order_consume);
r2 = y | (r1&0);
r3 = z + (r1-r1);
r4 = (&E)[r1*0];

, где простая стратегия переименования r1 и превращения его в «энергозависимый»"(как volatile, не оптимизируемый, кроме как в регистре) в промежуточном коде приводит к правильному поведению" потребления "(зависящей от значения / адреса) для каждой операции.

BONUS QUESTION

Doлюбой процессор напрямую поддерживаетт зависимые константы?Это инструкция «установить немедленное значение», которая вводит явную зависимость константы от значения регистра:

load.i.dep r1,8,r4 ; sets r1 to 8 but dependency on value of r4 is respected
lea r0,r0,r1       ; r0 += r1, r0 depends on r4
load.w r2,r1       ; loads one word at r1 to r2 only after r4 is known
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...