Вход/Регистрация
Разработка ядра Linux
вернуться

Лав Роберт

Шрифт:

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

b
и
а
выполнятся не в том порядке. Функции
rmb
и
wmb
соответствуют инструкциям, которые заставляют процессор выполнить все незаконченные операции чтения и записи перед тем, как продолжить работу далее.

Рассмотрим простой пример случая, когда можно использовать функцию

read_barrier_depends
вместо функции
rmb
. В этом примере изначально переменная
а
равна 1,
b
— 2, а
p
—
&b
.

Поток 1 Поток 2

а=3; -

mb; -

p=&а; pp=p;

– read_barrier_depends;

– b=*pp;

Снова без использования барьеров памяти появляется возможность того, что переменной

b
будет присвоено значение
*pp
до того, как переменной
pp
будет присвоено значение переменной
p
. Функция
read_barrier_depends
обеспечивает достаточный барьер, так как считывание значения
*pp
зависит от считывания переменной
p
. Здесь также будет достаточно использовать функцию
rmb
, но поскольку операции чтения зависимы между собой, то можно использовать потенциально более быструю функцию
read_barrier_depends
. Заметим, что в обоих случаях требуется использовать функцию
mb
для того, чтобы гарантировать необходимый порядок выполнения операций чтения-записи в потоке 1.

Макросы

smp_rmb
,
smp_wmb
,
smp_mb
и
smpread_barrier_depends
позволяют выполнить полезную оптимизацию. Для SMP-ядра они определены как обычные барьеры памяти, а для ядра, рассчитанного на однопроцессорную машину, — только как барьер компилятора. Эти SMP-варианты барьеров можно использовать, когда ограничения на порядок выполнения операций являются специфичными для SMP-систем.

Функция

barrier
предотвращает возможность оптимизации компилятором операций считывания и записи данных, если эти операции находятся по разные стороны от вызова данной функции (т.е. запрещает изменение порядка операций). Компилятор не изменяет порядок операций записи и считывания в случаях, когда это может повлиять на правильность выполнения кода, написанного на языке С, или на существующие зависимости между данными. Однако у компилятора нет информации о событиях, которые могут произойти вне текущего контекста. Например, компилятор не может иметь информацию о прерываниях, в контексте которых может выполняться считывание данных, которые в данный момент записываются. Например, по этой причине может оказаться необходимым гарантировать, что операция записи выполнится перед операцией считывания. Указанные ранее барьеры памяти работают и как барьеры компилятора, но барьер компилятора значительно быстрее, чем барьер памяти (практически не влияет на производительность). Использование барьера компилятора на практике является опциональным, так как он просто предотвращает возможность того, что компилятор что-либо изменит.

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

Таблица 9.10. Средства установки барьеров компилятора и памяти

Барьер Описание
rmb
Предотвращает изменение порядка выполнения операций чтения данных из памяти при переходе через барьер
read_barrier_depends
Предотвращает изменение порядка выполнения операций чтения данных из памяти при переходе через барьер, но только для операций чтения, которые зависимы друг от друга
wmb
Предотвращает изменение порядка выполнения операций записи данных в память при переходе через барьер
mb
Предотвращает изменение порядка выполнения операций чтения и записи данных при переходе через барьер
smp_rmb
Для SMP-ядер эквивалентно функции
rmb
, а для ядер, рассчитанных на однопроцессорные машины, эквивалентно функции
barrier
smp_read_barrier_depends
Для SMP-ядер эквивалентно функции
read_barrier_depends
, а для ядер, рассчитанных на однопроцессорные машины, эквивалентно функции
barrier
smp_wmb
Для SMP-ядер эквивалентно функции
wmb
, а для ядер, рассчитанных на однопроцессорные машины, эквивалентно функции
barrier
smp_mb
Для SMP-ядер эквивалентно функции
mb
, а для ядер, рассчитанных на однопроцессорные машины, эквивалентно функции
barrier
barrier
Предотвращает оптимизации компилятора по чтению и записи данных при переходе через барьер

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

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

Резюмирование по синхронизации

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

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

Глава 10

Таймеры и управление временем

Отслеживание хода времени очень важно для ядра. Большое количество функций, которые выполняет ядро, управляются временем (time driven), в отличие от тех функций, которые выполняются по событиям [53] (event driven). Некоторые из этих функций выполняются периодически, как, например, балансировка очередей выполнения планировщика или обновление содержимого экрана. Такие функции вызываются в соответствии с постоянным планом, например 100 раз в секунду. Другие функции, такие как отложенные дисковые операции ввода-вывода, ядро планирует на выполнение в некоторый относительный момент времени в будущем. Например, ядро может запланировать работу на выполнение в момент времени, который наступит позже текущего на 500 миллисекунд. Наконец, ядро должно вычислять время работы системы (uptime), а также текущую дату и время.

53

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

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

  • Читать дальше
  • 1
  • ...
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: