Как вы можете гарантировать, что ваш код выполняется без изменений во времени выполнения из-за кэша?

StackOverflow https://stackoverflow.com/questions/69049

Вопрос

Во встроенном приложении (написанном на C, на 32-разрядном процессоре) с жесткими ограничениями в реальном времени время выполнения критического кода (особенно прерываний) должно быть постоянным.

Как вы гарантируете, что временная изменчивость не будет введена при исполнении из-за кода, в частности, из-за кэшей процессора (будь то L1, L2 или L3)?

Обратите внимание, что мы обеспокоены поведением кэша из-за Огромный влияние, которое это оказывает на скорость выполнения (иногда более 100: 1 по сравнению сдоступ к оперативной памяти).Вариативность, вносимая из-за специфической архитектуры процессора, далеко не сравнима с объемом кэша.

Это было полезно?

Решение

Если вы можете получить доступ к оборудованию или поработать с кем-то, кто может, вы можете отключить кэш.Некоторые процессоры имеют вывод, который, если подключить его к заземлению вместо питания (или, возможно, другим способом), отключит все внутренние кэши.Это даст предсказуемость, но не скорость!

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

Наконец, если скорость действительно имеет значение - тщательно спроектируйте программное обеспечение и данные, как в старые добрые времена программирования для древнего 8-разрядного процессора - держите их достаточно маленькими, чтобы все это поместилось в кэш L1.Я всегда поражаюсь тому, насколько встроенные кэши в наши дни больше, чем вся оперативная память миникомпьютера прошлых лет (mumble-decade).Но это будет тяжелая работа, требующая сообразительности.Удачи вам!

Другие советы

Две возможности:

Полностью отключите кэш.Приложение будет работать медленнее, но без каких-либо изменений.

Предварительно загрузите код в кэш и "заблокируйте его".Большинство процессоров предоставляют механизм для этого.

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

Этот ответ прозвучит ехидно, но он призван заставить вас задуматься:

Запускайте код только один раз.

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

Далее вы сталкиваетесь с непредсказуемостью из-за производительности кэша, задержки памяти, дискового ввода-вывода и так далее.Все это сводится к одному;иногда требуется время, чтобы передать информацию в процессор, где ваш код может ее использовать.Включая время, необходимое для извлечения / декодирования самого вашего кода.

Кроме того, насколько большая разница приемлема для вас?Возможно, вас устраивают 40 миллисекунд или 10 наносекунд.

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

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

Если вы сделаете все вызовы функций в критическом коде "встроенными" и сведете к минимуму количество имеющихся у вас переменных, чтобы вы могли позволить им иметь тип 'register'.Это должно увеличить время работы вашей программы.(Вероятно, вам придется скомпилировать его особым образом, поскольку в наши дни компиляторы, как правило, игнорируют ваши теги "register")

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

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

Если при выполнении вашего кода произойдет прерывание, это займет больше времени.Включены ли у вас прерывания / исключения?

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

/Аллан

Поймите свой наихудший вариант выполнения сложных операций и используйте таймеры.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top