Как GCC знает, что регистр должен быть сброшен в память, когда объявлен клоббер памяти? - PullRequest
0 голосов
/ 26 января 2019

Расширенное руководство по Asm https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html говорит следующее о клоббере «памяти»:

Клопбер «памяти» сообщает компилятору, что код сборки выполняет чтение или запись в памятьэлементы, отличные от перечисленных в операндах ввода и вывода (например, доступ к памяти, на которую указывает один из входных параметров).Чтобы гарантировать, что память содержит правильные значения, GCC может потребоваться сбросить определенные значения регистра в память перед выполнением asm.Кроме того, компилятор не предполагает, что какие-либо значения, считанные из памяти до asm, остаются неизменными после этого asm;он перезагружает их по мере необходимости.Использование «памяти» клоббера эффективно формирует барьер памяти для чтения / записи для компилятора.

Я запутался в решении сбросить память.До кода asm, как GCC узнает, что регистр служит кешем для ячейки памяти и, следовательно, должен быть сброшен в память?И является ли это частью когерентности кэша (я думал, что когерентность кэша была аппаратным поведением)?После кода asm, как GCC распознает регистр как кеш, и, в следующий раз, когда регистр считывается, вместо этого решается чтение из памяти, поскольку кеш может быть старым?

1 Ответ

0 голосов
/ 26 января 2019

Перед кодом ассемблера, как GCC узнает, что регистр служит кешем для области памяти и, следовательно, должен быть сброшен в память?

Поскольку GCC является единственнымкто генерирует этот код

Как правило, с точки зрения GCC:

[C code to compile]
[your inline asm with clobber]
[C code to compile]

GCC генерирует инструкции по сборке до и после встроенного ассемблера, следовательно, он знает все до и после него.Теперь, поскольку клоббер памяти означает барьер памяти sw, применяется следующее:

[GCC generated asm]
[compiler memory barrier]
[GCC generated asm]

Таким образом, GCC генерирует сборку до и после барьера и знает, что он не может иметь доступ к памяти, пересекающий барьер памяти.По сути, с точки зрения GCC, есть код для компиляции, затем барьер памяти, затем больше кода для компиляции, и все, единственное ограничение, которое применяется барьером памяти, заключается в том, что сгенерированный GCC код не должен иметь доступ к памяти, пересекающий этот барьер.

Таким образом, если, например, GCC загружает регистр со значением из памяти, изменяет его и сохраняет его обратно в память, загрузка и сохранение не могут пересечь барьер.В зависимости от кода, они должны находиться до или после барьера (или дважды с обеих сторон).

Я бы порекомендовал вам прочитать эту связанную SO тему .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...