Как читать устаревшие значения на x86 - PullRequest
0 голосов
/ 04 ноября 2018

Моя цель - читать устаревшие и устаревшие значения памяти без когерентности кеша. Я попытался использовать prefetchnta для выполнения невременной загрузки, но он не смог получить устаревшие значения. Я пытаюсь выполнить потоковую передачу из памяти в память с прямым доступом, но у меня возникли небольшие проблемы из-за огромного количества базовых знаний, необходимых для продолжения моего текущего проекта. В настоящее время я пытаюсь возиться с udmabuf , но даже это происходит медленно. Следует отметить, что в идеале я хотел бы игнорировать содержимое всех кэшей ЦП, включая текущий ЦП.

Чтобы обосновать причину: я занимаюсь разработкой программного обеспечения, которое можно использовать для подтверждения правильности программ, написанных для энергонезависимой памяти. Поскольку кэш-память ЦП является энергозависимой, кэш-память обратной записи ЦП по-прежнему будет нестабильной, и необходимо учитывать произвольный характер их обратной записи в память.

Я был бы искренне признателен, если бы кто-нибудь дал мне несколько советов о том, как действовать. Я не возражаю копаться в ядре Linux, так как на самом деле я делаю это сейчас, и я не возражаю против его изменения, мне просто нужно небольшое руководство в правильном направлении.

1 Ответ

0 голосов
/ 05 ноября 2018

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

Вы можете выполнять слабо упорядоченную загрузку из областей памяти WC (с комбинированием записи) (с помощью prefetchnta или SSE4 movntdqa), но они, вероятно, все еще согласованы на уровне физических адресов.

@ прокомментировала MargaretBloom

IIRC Intel предупреждает разработчика о множественном отображении с разными типами кэша, что в данном случае может быть действительно полезным.

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


Я не знаю, возможно ли по-прежнему создавать некогерентный DMA с устройством PCI / PCIe, но это может быть вашей единственной надеждой на получение реального содержимого DRAM без прохождения через кэш. (Большинство (?) DMA в современных системах x86 когерентно, что хорошо для производительности и возможно, потому что контроллеры памяти встроены в ЦП. Так, на процессорах Intel системный агент может отслеживать теги L3, чтобы увидеть, Эта строка кэшируется в любом месте на кристалле параллельно с отправкой запроса в контроллер памяти.)


Существует инструкция INVD , которая делает недействительными все кэши без предварительной записи, но я думаю, что это включает общий кэш L3 и, возможно, частные кеши всех остальных ядер . Таким образом, вы практически не можете использовать его в системе Linux, где другие ядра потенциально находятся в процессе работы; вы могли бы испортить структуры данных ядра, используя его, а также имитировать сбой питания на машине с NVDIMM для интересующего вас процесса.

Может быть, если вы как-то отключили все остальные ядра ЦП и отключили прерывания на одном работающем ядре

Затем снова включите прерывания. Обработчики прерываний могут в конечном итоге приводить к кэшированию некоторых данных ядра, а некоторых - в памяти, или приводить драйверы устройств к синхронизации с аппаратным обеспечением, если какие-либо прерывания обрабатываются между wbinvd и invd.

...