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

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

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

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

Ответы [ 7 ]

2 голосов
/ 16 сентября 2008

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

2 голосов
/ 16 сентября 2008

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

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

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

2 голосов
/ 16 сентября 2008

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

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

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

0 голосов
/ 16 сентября 2008

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

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

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

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

0 голосов
/ 16 сентября 2008

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

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

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

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

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

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

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

0 голосов
/ 16 сентября 2008

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

0 голосов
/ 16 сентября 2008

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

/ Allan

...