Копирование при записи ( КПС ), иногда упоминается как неявное совместное использование [1] или затенения , [2] представляет собой метод управления ресурсами используется в компьютерном программировании , чтобы эффективно реализовать «дубликат» или «копировать» операции на модифицируемых ресурсов. [3]Если ресурс дублируется, но не изменяется, нет необходимости создавать новый ресурс; ресурс может быть разделен между копией и оригиналом. Модификации все равно должны создавать копию, отсюда и техника: операция копирования откладывается до первой записи. Совместное использование ресурсов таким образом позволяет значительно снизить потребление ресурсов немодифицированными копиями, добавляя при этом небольшие накладные расходы на операции изменения ресурсов.
В управлении виртуальной памятью
Копирование при записи находит свое основное применение в обмене виртуальной памяти в операционных системах процессов , в реализации системы вилки вызова . Обычно процесс не изменяет память и немедленно выполняет новый процесс, полностью заменяя адресное пространство. Таким образом, было бы расточительно копировать всю память процесса во время вилки, и вместо этого используется техника копирования при записи.
Копирование при записи может быть эффективно реализовано с использованием таблицы страниц , помечая определенные страницы памяти как доступные только для чтения и ведя подсчет количества ссылок на страницу. Когда данные записываются на эти страницы, ядро перехватывает попытку записи и выделяет новую физическую страницу, инициализированную данными копирования при записи, хотя выделение можно пропустить, если имеется только одна ссылка. Затем ядро обновляет таблицу страниц новой (доступной для записи) страницей, уменьшает количество ссылок и выполняет запись. Новое распределение гарантирует, что изменение в памяти одного процесса не будет видно в памяти другого.
Методика копирования при записи может быть расширена для поддержки эффективного распределения памяти за счет заполнения страницы физической памяти нулями. Когда память выделена, все возвращенные страницы ссылаются на страницу нулей и все помечаются как копирование при записи. Таким образом, физическая память не выделяется для процесса до тех пор, пока данные не будут записаны, что позволяет процессам резервировать больше виртуальной памяти, чем физическая память, и использовать память редко, рискуя исчерпать виртуальное адресное пространство. Комбинированный алгоритм аналогичен пейджингу по запросу . [3]
Копирование при записи страница также используется в Linux ядро «s ядро же страницы слияния функций. [4]
Загрузка библиотек для приложения также является использованием техники копирования при записи. Динамический компоновщик отображает библиотеки как частные, как показано ниже. Любое действие записи в библиотеки вызовет COW в управлении виртуальной памятью.
openat ( AT_FDCWD , "/lib64/libc.so.6" , O_RDONLY | O_CLOEXEC ) = 3 MMAP ( NULL , 3906144 , PROT_READ | PROT_EXEC , MAP_PRIVATE | опция MAP_DENYWRITE , 3 , 0 ) ММАП ( 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]
std :: string x ( "Привет" );std :: string y = x ; // x и y используют один и тот же буферy + = ", Мир!" ; // теперь y использует другой буфер // x все еще использует тот же старый буфер
В языке программирования PHP все типы, кроме ссылок, реализованы как копирование при записи. Например, строки и массивы передаются по ссылке, но при изменении они дублируются, если имеют ненулевое количество ссылок. Это позволяет им действовать как типы значений без проблем с производительностью, связанных с копированием при назначении или их неизменяемостью. [7]
В структуре Qt многие типы копируются при записи («неявно разделяются» в терминах Qt). Qt использует атомарные операции сравнения и замены для увеличения или уменьшения внутреннего счетчика ссылок. Поскольку копии дешевы, типы Qt часто могут безопасно использоваться несколькими потоками без необходимости использования механизмов блокировки, таких как мьютексы . Таким образом, преимущества COW проявляются как в однопоточных, так и в многопоточных системах. [8]
В хранилище компьютера
COW также может использоваться в качестве основного механизма для моментальных снимков , например, предоставляемых управлением логическими томами , файловыми системами, такими как Btrfs и ZFS , [9] и серверами баз данных, такими как Microsoft SQL Server . Обычно моментальные снимки хранят только измененные данные и хранятся рядом с основным массивом, поэтому они являются лишь слабой формой инкрементного резервного копирования и не могут заменить полную резервную копию . [10] Некоторые системы также используют метод COW, чтобы избежать нечетких резервных копий , которые в противном случае возникают, когда какой-либо файл в наборе файлов, для которых выполняется резервное копирование, изменяется во время этого резервного копирования.
При создании снимков используются два метода:
- Перенаправление при записи или ROW: исходное хранилище никогда не изменяется. Когда делается запрос на запись, он перенаправляется от исходных данных в новую область хранения.
- Копирование при записи или COW: когда делается запрос на запись, данные копируются в новую область хранения, а затем исходные данные изменяются.
Несмотря на их названия, копирование при записи обычно относится к первой технике. COW выполняет две записи данных по сравнению с записью ROW; его сложно реализовать эффективно, и поэтому он используется нечасто.
Технику копирования при записи можно использовать для имитации хранилища для чтения и записи на носителях, которые требуют выравнивания износа или физически записывают один раз, много читают .
Формат образа диска qcow2 (копия QEMU при записи) использует технику копирования при записи для уменьшения размера образа диска.
Некоторые live CD (и live USB ) используют методы копирования при записи, чтобы создать впечатление, что вы можете добавлять и удалять файлы в любом каталоге, фактически не внося никаких изменений в CD (или USB-накопитель).
В высоконадежном программном обеспечении
Phantom OS использует COW на всех уровнях, а не только в базе данных или файловой системе. В любой момент компьютер с этой системой может выйти из строя, а затем, когда он снова запустится, программное обеспечение и операционная система возобновят работу. Может быть потеряно только небольшое количество работы.
Основной подход заключается в том, что все данные программы хранятся в виртуальной памяти. По некоторому расписанию сводка всех данных программного обеспечения записывается в виртуальную память, образуя журнал, в котором отслеживается текущее значение и расположение каждого значения.
Когда компьютер выходит из строя, последняя копия журнала и другие данные остаются в безопасности на диске. Когда работа возобновляется, программное обеспечение операционной системы считывает журнал для восстановления согласованных копий всех программ и данных.
Этот подход использует копирование при записи на всех уровнях всего программного обеспечения, включая прикладное программное обеспечение. Для этого требуется поддержка в рамках языка программирования приложений. На практике Phantom OS разрешает только языки, генерирующие байт-код Java .
Смотрите также
- Распределить на промывке
- Btrfs
- Пейджинг по запросу
- Dirty COW - уязвимость компьютерной безопасности для ядра операционной системы Linux.
- Схема наилегчайшего веса
- Управление памятью
- Постоянная структура данных
- ReFS
- Снимок (компьютерное хранилище)
- Виртуальная память
Рекомендации
- ^ «Неявный обмен» . Qt Project . Дата обращения 4 августа 2016 .
- ^ Родех, Охад (1 февраля 2008 г.). «B-деревья, затенение и клоны» (PDF) . ACM-транзакции в хранилище . 3 (4): 1. CiteSeerX 10.1.1.161.6863 . DOI : 10.1145 / 1326542.1326544 . S2CID 207166167 . Дата обращения 4 августа 2016 .
- ^ а б Бове, Даниэль Пьер; Чезати, Марко (01.01.2002). Понимание ядра Linux . O'Reilly Media. п. 295. ISBN 9780596002138.
- ^ Аббас Али. «Процесс слияния одинаковых страниц ядра» . alouche.net . Архивировано из оригинала 8 -го августа 2016 года . Дата обращения 4 августа 2016 .
- ^ Мейерс, Скотт (2012), Эффективный STL , Addison-Wesley, стр. 64–65, ISBN 9780132979184
- ^ «Модификации параллелизма в базовой строке» . Открытые стандарты . Проверено 13 февраля 2015 года .
- ^ Паули, Жюльен; Феррара, Энтони; Попов, Никита (2013). «Управление памятью» . www.phpinternalsbook.com . Книга о внутреннем устройстве PHP . Дата обращения 4 августа 2016 .
- ^ «Потоки и неявно общие классы» . Qt Project . Дата обращения 4 августа 2016 .
- ^ Касампалис, Сакис (2010). «Копирование при анализе производительности и реализации файловых систем на основе записи» (PDF) . п. 19 . Проверено 11 января 2013 года .
- ^ Чиен, Тим. «Снимки НЕ ЯВЛЯЮТСЯ резервными копиями» . www.oracle.com . Oracle . Дата обращения 4 августа 2016 .