#ос #память #ассемблер #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
Копируется страница целиком. Как именно - скорее всего именно побайтово. Надо смотреть исходники ядра.
Комментариев нет:
Отправить комментарий