Копирование при записи - Copy-on-write

Копирование при записи (КОРОВА), иногда называемый неявное совместное использование[1] или же слежка,[2] это метод управления ресурсами, используемый в компьютерное программирование для эффективной реализации операции «дублирования» или «копирования» на изменяемых ресурсах.[3] Если ресурс дублируется, но не изменяется, нет необходимости создавать новый ресурс; ресурс может использоваться совместно копией и оригиналом. Модификации все равно должны создавать копию, отсюда и техника: операция копирования откладывается до первой записи. Совместное использование ресурсов таким образом позволяет значительно снизить потребление ресурсов немодифицированными копиями, добавляя при этом небольшие накладные расходы на операции изменения ресурсов.

В управлении виртуальной памятью

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

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

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

Страницы копирования при записи также используются в Ядро Linux с слияние одной страницы ядра особенность.[4]

Загрузка библиотек для приложения также является использованием техники копирования при записи. Динамический компоновщик отображает библиотеки как частные, как показано ниже. Любое действие записи в библиотеки вызовет COW в управлении виртуальной памятью.

открывать(AT_FDCWD, "/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3mmap(НОЛЬ, 3906144, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0)mmap(0x7f8a3ced4000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1b0000)

В программном обеспечении

COW также используется в библиотека, заявление и система код.

В многопоточный систем, COW может быть реализована без использования традиционных запирание и вместо этого используйте сравнивать и менять местами для увеличения или уменьшения внутреннего счетчика ссылок. Поскольку исходный ресурс никогда не будет изменен, его можно безопасно скопировать несколькими потоками (после увеличения счетчика ссылок) без необходимости дорогостоящей блокировки, такой как мьютексы. Если счетчик ссылок становится равным 0, то по определению только 1 поток держал ссылку, поэтому ресурс можно безопасно освободить от памяти, опять же без использования дорогостоящих механизмов блокировки. Таким образом, преимущество отсутствия копирования ресурса (и, как следствие, повышение производительности по сравнению с традиционным глубоким копированием) будет справедливо как для однопоточных, так и для многопоточных систем.

Примеры

В нить класс, предоставленный Стандартная библиотека C ++ был специально разработан, чтобы разрешить реализации копирования при записи в исходном стандарте C ++ 98,[5] но не в новом стандарте C ++ 11:[6]

стандартное::нить Икс("Привет");стандартное::нить у = Икс;  // x и y используют один и тот же буферу += ", Мир!";    // теперь y использует другой буфер                    // x по-прежнему использует тот же старый буфер

в PHP язык программирования, все типы, кроме ссылок, реализованы как копирование при записи. Например, строки и массивы передаются по ссылке, но при изменении они дублируются, если имеют ненулевое количество ссылок. Это позволяет им действовать как типы значений без проблем с производительностью, связанных с копированием при назначении или их неизменяемостью.[7]

в Qt framework, многие типы копируются при записи («неявно разделяются» в терминах Qt). Qt использует атомарный сравнивать и менять местами операции для увеличения или уменьшения внутреннего счетчика ссылок. Поскольку копии дешевы, типы Qt часто могут безопасно использоваться несколькими потоками без необходимости использования механизмов блокировки, таких как мьютексы. Таким образом, преимущества COW проявляются как в однопоточных, так и в многопоточных системах.[8]

В хранилище компьютера

COW также может использоваться в качестве основного механизма для снимки, например, предоставленные управление логическими томами, файловые системы, такие как Btrfs и ZFS,[9] и серверы баз данных, такие как Microsoft SQL Server. Обычно снимки хранят только измененные данные и хранятся рядом с основным массивом, поэтому они являются лишь слабой формой инкрементное резервное копирование и не может заменить полная резервная копия.[10] Некоторые системы также используют технику COW, чтобы избежать нечеткие резервные копии, в противном случае возникает, когда какой-либо файл в наборе файлов, для которого выполняется резервное копирование, изменяется во время этого резервного копирования.

При создании снимков есть два метода:

  1. Перенаправление при записи или ROW: исходное хранилище никогда не изменяется. Когда делается запрос на запись, он перенаправляется от исходных данных в новую область хранения.
  2. Копирование при записи или COW: когда делается запрос на запись, данные копируются в новую область хранения, а затем исходные данные изменяются.

Несмотря на их названия, копирование при записи обычно относится к первой технике. COW выполняет две записи данных по сравнению с записью ROW; его сложно реализовать эффективно, и поэтому он используется нечасто.

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

В qcow2 (Копирование при записи QEMU) формат образа диска использует метод копирования при записи для уменьшения размера образа диска.

Немного Live CDЖивые USB ) используют методы копирования при записи, чтобы создать впечатление, что вы можете добавлять и удалять файлы в любом каталоге, фактически не делая никаких изменений на компакт-диске (или USB-накопителе).

В программном обеспечении высокой надежности

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

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

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

Этот подход использует копирование при записи на всех уровнях всего программного обеспечения, включая прикладное программное обеспечение. Это требует поддержки в рамках языка программирования приложений. На практике Phantom OS разрешает только языки, генерирующие байтовые коды Java.

Смотрите также

Рекомендации

  1. ^ «Неявный обмен». Qt Project. Получено 4 августа 2016.
  2. ^ Родех, Охад (1 февраля 2008 г.). "B-деревья, затенение и клоны" (PDF). ACM-транзакции в хранилище. 3 (4): 1. CiteSeerX  10.1.1.161.6863. Дои:10.1145/1326542.1326544. S2CID  207166167. Получено 4 августа 2016.
  3. ^ а б Бове, Даниэль Пьер; Чезати, Марко (01.01.2002). Понимание ядра Linux. O'Reilly Media. п. 295. ISBN  9780596002138.
  4. ^ Аббас Али. «Процесс слияния одинаковых страниц ядра». alouche.net. Архивировано из оригинал 8 августа 2016 г.. Получено 4 августа 2016.
  5. ^ Мейерс, Скотт (2012), Эффективный STL, Addison-Wesley, pp. 64–65, ISBN  9780132979184
  6. ^ «Модификации параллелизма в базовой строке». Открытые стандарты. Получено 13 февраля 2015.
  7. ^ Паули, Жюльен; Феррара, Энтони; Попов, Никита (2013). "Управление памятью". www.phpinternalsbook.com. Книга о внутренностях PHP. Получено 4 августа 2016.
  8. ^ «Потоки и неявно общие классы». Qt Project. Получено 4 августа 2016.
  9. ^ Касампалис, Сакис (2010). «Копирование при анализе производительности и реализации файловых систем на основе записи» (PDF). п. 19. Получено 11 января 2013.
  10. ^ Чиен, Тим. «Снимки НЕ ЯВЛЯЮТСЯ резервными копиями». www.oracle.com. Oracle. Получено 4 августа 2016.