Страницы

Поиск по вопросам

среда, 25 декабря 2019 г.

Теоретический вопрос о “Copy On Write”

#ос #память #ассемблер #linux


Доброго времени суток.
После вызова fork() мы получаем два процесса с абсолютно идентичными адресными пространствами.
Давным-давно в BSD система реально выделяла нужное количество новой памяти и копировала
туда данные процесса-родителя во время вызова fork(). Сейчас есть технология копирования
при изменении. Мне вот что интересно:

Что именно копируется при изменении? Допустим мы вызвали функцию в дочернем процессе,
значит как минимум записали кое-что в стек. Ядро скопирует одну измененную страницу,
весь сегмент стека, все сегменты приложения или еще что-то?
Как происходит копирование? Неужели по-байтово? Или процессор может копировать например
целую страницу за 1 инструкцию? Я о таком никогда не слышал...
    


Ответы

Ответ 1



Копируется страница. Копирование исполняет тот же код, что и обычное копирование аргументов из пространства пользователя и по факту не отличается от быстрых вариантов реализации memcpy. Так для amd64 существует три реализации (вызываются из обработчика страничного прерывания, фактически отсюда): Базовая, copy_user_generic_unrolled общий алгоритм: копирование происходит через четыре 64-битных регистра по 64 байта за итерацию цикла. Базовая на основе строковых инструкций, copy_user_generic_string, с использованием rep; movsq. По факту копирование целой страницы происходит в течение выполнения одной микрокоманды — movsq. Алгоритм доступен на системах предоставляющих расширение rep_good (см. flags в /proc/cpuinfo). Быстрая на основе строковых инструкций, copy_user_enhanced_fast_string, аналогично предыдущей, но использует rep; movsb на системах, с поддержкой расширения erms (см. flags в /proc/cpuinfo) — особо быстрой системой реализации копирования.

Ответ 2



Копируется страница целиком. Как именно - скорее всего именно побайтово. Надо смотреть исходники ядра.

Комментариев нет:

Отправить комментарий