msync(MS_SYNC)
От: valuea  
Дата: 25.04.16 20:39
Оценка:
Господа, есть несколько потоков, которые пишут в memmapped файл. По заверешнию записи, каждый поток скидивает измненения на диск, посредсвом msync(MS_SYNC). И тут у меня возникли сомнения относительно производительности, поэтому хотел бы уточнить варианты реализации механизма блокировок в функции msync.
1. На все время выполнения msync блокируется все адресное пространство полностью (то есть все потоки, которые пытаются выполнить запись данных в отображемый участок памяти блокируются до заверешния msync)
2. На все время выполнения msync блокируются только измененные страницы памяти, подлежащие сбросу на диск.
3. Блокируются только измененные сплошные последовательности страниц памяти, подлежащие сбросу на диск, причем блокируются только на время выполнения сброса на диск данной последовательности страниц
4. Какой-либо еще вариант...
Ну и кроме того, msync "сам себя" блокирует? То есть допустим, вызов msync для 0-ой страницы файла в одном потоке, будет дожидаться завершения выполнения msync в другом потоке с диапазоном 1-N страниц?
Re: msync(MS_SYNC)
От: watchmaker  
Дата: 26.04.16 18:09
Оценка:
Здравствуйте, valuea, Вы писали:

V>Господа, есть несколько потоков, которые пишут в memmapped файл. По заверешнию записи, каждый поток скидивает измненения на диск, посредсвом msync(MS_SYNC). И тут у меня возникли сомнения относительно производительности, поэтому хотел бы уточнить варианты реализации механизма блокировок в функции msync.

С одной стороны про производительность сомнения, с другой стороны ни названия ОС, ни тип файловой системы не указан. Интерес сугубо теоретический? :)

V>1. На все время выполнения msync блокируется все адресное пространство полностью (то есть все потоки, которые пытаются выполнить запись данных в отображемый участок памяти блокируются до заверешния msync)

V>2. На все время выполнения msync блокируются только измененные страницы памяти, подлежащие сбросу на диск.
V>3. Блокируются только измененные сплошные последовательности страниц памяти, подлежащие сбросу на диск, причем блокируются только на время выполнения сброса на диск данной последовательности страниц
V>4. Какой-либо еще вариант...

Зачем ОС что-то блокировать? Один процесс вызвал msync, а другой изменил записываемые данные? Разумным будет считать, что это обычная гонка в программе. И что это не совсем задача mmap заниматься синхронизацией таких вещей. Если программе важна блокировка, то она сама должна создать какой-то мьютекс (или что-то ещё), и с его помощью реализовать вариант 1, 2 или 3.
Иначе, можно считать, что ничего никогда не блокируется: один поток может успеть записать новые данные в страницу прямо перед её сбросом, другой поток может записать данные в страницу сразу же после её сброса, сделав её тут же снова грязной.

V>Ну и кроме того, msync "сам себя" блокирует? То есть допустим, вызов msync для 0-ой страницы файла в одном потоке, будет дожидаться завершения выполнения msync в другом потоке с диапазоном 1-N страниц?

Да легко. Опять же в зависимости от ОС и ФС.
Про ext3 с data=ordered даже говорят, что msync может ждать завершения записи других файлов в системе, с которыми работают совсем другие программы. Так что в этом месте я бы тоже ожидал любой подставы :)
Re[2]: msync(MS_SYNC)
От: valuea  
Дата: 27.04.16 20:28
Оценка:
Здравствуйте, watchmaker, Вы писали:
W>Интерес сугубо теоретический?
И теоретический и практический. ОС — FreeBSD либо NetBSD. Файловая система — ну тут уже от меня не зависит. Скорей всего новомодный (или уже не новомодный) ZFS.
W>Зачем ОС что-то блокировать? Один процесс вызвал msync, а другой изменил записываемые данные? Разумным будет считать, что это обычная гонка в программе.
Ну не совсем гонка. С одной стороны хочется гарантировать, что в процессе сброса грязных страниц на диск никакой другой поток не "подпортит" их, перезаписав какую-то часть данных, с другой стороны не хочется полностью блокировать процесс записи в память потоками, когда один из них сбрасывает страницы на диск. Раз уж механизм mmap имеет полный контроль над участком памяти в которую отображается файл, то был уверен, что на время копирования в кэш ОС ну или там в буфер контроллера, какая-то блокировка все-же выставляется.
W>Если программе важна блокировка, то она сама должна создать какой-то мьютекс (или что-то ещё), и с его помощью реализовать вариант 1, 2 или 3.
Да, если действительно mmap никак не ограничивает процесс записи в память, то да, наверно надо смотреть в сторону fcntl(F_SETLKW) либо что-то свое делать.
W>Так что в этом месте я бы тоже ожидал любой подставы
Еще один довод в пользу своего решения. Вообще интересно, хранилища вроде MySQL или Oracle, ну или NoSQL решения какие-нибудь, mmap используют или свой менеджер с прямой записью в файл?
Re[3]: msync(MS_SYNC)
От: andrey.desman  
Дата: 27.04.16 21:37
Оценка:
Здравствуйте, valuea, Вы писали:

V>Ну не совсем гонка. С одной стороны хочется гарантировать, что в процессе сброса грязных страниц на диск никакой другой поток не "подпортит" их, перезаписав какую-то часть данных, с другой стороны не хочется полностью блокировать процесс записи в память потоками, когда один из них сбрасывает страницы на диск. Раз уж механизм mmap имеет полный контроль над участком памяти в которую отображается файл, то был уверен, что на время копирования в кэш ОС ну или там в буфер контроллера, какая-то блокировка все-же выставляется.


Не скажу про BSD, но скорее всего будет так жк как в линуксе.
А в линуксе, твой ммап — это и есть кэш ОС. То есть никакого копирования не происходит. И у механизма mmap нет никакого контроля над записью в эту память. Отправка данных на диск — обычный DMA из этих же самых страниц. Вполне возможно, что диск не получит изменения, сделанные в окне после msync, но до DMA, так как они весьма вероятно останутся в кэше процессора, но возможно, что получит, кто его знает...

W>>Если программе важна блокировка, то она сама должна создать какой-то мьютекс (или что-то ещё), и с его помощью реализовать вариант 1, 2 или 3.

V>Да, если действительно mmap никак не ограничивает процесс записи в память, то да, наверно надо смотреть в сторону fcntl(F_SETLKW) либо что-то свое делать.

Никак. Надо делать свои блокировки.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.