LINUX.ORG.RU

насколько полох хорош алгоритм копирования файла


0

0

1) делаем mmap всего исходного файла

2)вызываем write на отмапленную оласть памяти

копируемый файл не предполагается размером в более чем несколько метров.

рассматриваю как альтернативу read/write в цикле.

★★★★★

кстати mmap делается с флагами MAP_PRIVATE|MAP_NORESERVE

cvv ★★★★★
() автор топика

> насколько полох хорош алгоритм копирования файла
> 1) делаем mmap всего исходного файла
> 2)вызываем write на отмапленную оласть памяти
> копируемый файл не предполагается размером в более чем несколько
> метров.
>
> рассматриваю как альтернативу read/write в цикле.

При размере файла в несколько Mb не вижу смысла в долгих размышлениях
- делай один read() всего файла и один write().
Или даже используй stdio - fopen()/fread()/fwrite(). Будет просто
и переносимо ;-)

HTH

Onanim
()
Ответ на: комментарий от Onanim

>Вдогонку - man 2 sendfile

Что с тобой? я тебя не узнаю ;-(

Эта штука работает только если один из файлов - регулярный, на двух регулярных - нет. по крайней мере так было до недавнего времени.

cvv ★★★★★
() автор топика
Ответ на: комментарий от cvv

> Что с тобой? я тебя не узнаю ;-(
> Эта штука работает только если один из файлов - регулярный, на двух
> регулярных - нет. по крайней мере так было до недавнего времени.

Ну да, это ж Linux а не Solaris :-(
Виноват, переоценил...

Onanim
()
Ответ на: комментарий от Motl

похоже на кривость мана:

Either or both of these file descriptors may refer to a socket (but see below).

и:

Presently the descriptor from which data is read cannot correspond to a socket, it must correspond to a file which supports mmap()-like operations.

cvv ★★★★★
() автор топика
Ответ на: комментарий от cvv

>Эта штука работает только если один из файлов - регулярный, на двух >регулярных - нет. по крайней мере так было до недавнего времени.

Достаточно с давних времен (сейчас глянул в 2.4.20) это работает для файлов. Общий смысл в том, что копирование из одной страницы кэша ядро само осуществляет в другую страницу кэша (без переключений контекстов ядро/процесс и накладных затрат в библиотеках ввода/вывода).

В 2.6 глянул мельком, вроде это должно работать и для сокетов, во всяком случае sendpage реализована для кучи протоколов (а для чего еще это может быть нужно?).

Для копирования больших файлов еше имеет смысл подумать о прямом вводе-выводе, чтобы не засирать кэш.

Murr ★★
()
Ответ на: комментарий от Murr

>Для копирования больших файлов еше имеет смысл подумать о прямом вводе-выводе, чтобы не засирать кэш.

обьясни подробнее

cvv ★★★★★
() автор топика
Ответ на: комментарий от Murr

>>Эта штука работает только если один из файлов - регулярный, на двух регулярных - нет. по крайней мере так было до недавнего времени.

>Достаточно с давних времен (сейчас глянул в 2.4.20) это работает для файлов. Общий смысл в том, что копирование из одной страницы кэша ядро само осуществляет в другую страницу кэша (без переключений контекстов ядро/процесс и накладных затрат в библиотеках ввода/вывода).

кажись ещё одна ошибка в advanced programming for linux.

cvv ★★★★★
() автор топика
Ответ на: комментарий от cvv

>обьясни подробнее

Я имел в виду man 2 open O_DIRECT

Обычное копирование через fread/fwrite, read/write, mmap, sendfile делает копирование через страничный кэш, т.е. страницами исходного и целевого файла вытесняет потенциально полезный кэш. Чтение/запись через O_DIRECT должно минимизировать использование(вытеснение) кэша и за счет этого повышение(неснижение то бишь) производительности после копирования.

Что до документации по Linux, то, по-моему, она несколько не поспевает... :)

Murr ★★
()
Ответ на: комментарий от Murr

понял, понял

а для файла открытого с o_direct mmap делать можно? а смысл есть?

cvv ★★★★★
() автор топика
Ответ на: комментарий от Murr

Murr:

> cvv:
>> Эта штука работает только если один из файлов - регулярный, на двух
>>регулярных - нет. по крайней мере так было до недавнего времени.

> Достаточно с давних времен (сейчас глянул в 2.4.20) это работает для файлов.

Чота сомневаюсь я, что sendfile() работает file->file в 2.6.
По крайней мере без патчей (http://wohnheim.fh-wedel.de/~joern/cowlink/)
вроде как не должен.
Желающие могут попробовать на своих машинах ;-)

HTH

Onanim
()
Ответ на: комментарий от Onanim

>Чота сомневаюсь я, что sendfile() работает file->file в 2.6.

Я тоже сомневаюсь после просмотра кода 2.6. Странно, что после 2.4 отказались от механизма zero-copy без sendpage. _Тогда_, как я писал, это работало. :-/

Murr ★★
()
Ответ на: комментарий от Murr

Вот код в 2.4:

nt file_send_actor(read_descriptor_t * desc, struct page *page, unsigned long offset , unsigned long size)
{
        ssize_t written;
        unsigned long count = desc->count;
        struct file *file = (struct file *) desc->buf;

        if (size > count)
                size = count;

        if (file->f_op->sendpage) {
                written = file->f_op->sendpage(file, page, offset,
                                               size, &file->f_pos, size<count);
        } else {
                char *kaddr;
                mm_segment_t old_fs;

                old_fs = get_fs();
                set_fs(KERNEL_DS);

                kaddr = kmap(page);
                written = file->f_op->write(file, kaddr + offset, size, &file->f_pos);
                kunmap(page);

                set_fs(old_fs);
        }
        if (written < 0) {
                desc->error = written;
                written = 0;
        }
        desc->count = count - written;
        desc->written += written;
        return written;
}

Murr ★★
()
Ответ на: комментарий от Murr

С mmap будет та проблема, что физически адреса mmap не сразу отобразятся на страницы файла и при копировании будут постоянные page faults... даже если кэш будет заполнен данными файла, то все равно будут page faults (их можно вылечить только при наличии привилегий с помощью mlock). Просто же кэш можно заполнить с madvise.

Я бы копировал с open(O_DIRECT)/read/write.

Murr ★★
()
Ответ на: комментарий от Murr

хм. а какие будут накладки на переключение контекстов? page fault будет ещё большие накладки создавать?

cvv ★★★★★
() автор топика
Ответ на: комментарий от Murr

>_Тогда_, как я писал, это работало. :-/

действительно странно для 2.2 тоже как будто работало.

похоже моя память стала меня основательно подводить ;-(

так что в какой-то мере я напрасно наехал на Onanim. Извиняюсь

cvv ★★★★★
() автор топика
Ответ на: комментарий от cvv

>хм. а какие будут накладки на переключение контекстов? page fault будет > ещё большие накладки создавать?

sorry, невнимательно прочитал. :( Если mmap/write, то переключений контекстов не будет. Будут page faults в самом ядре, не столь затратные, хотя было бы приятно и их избежать. Тут бы помог mlock (при наличии привилегий).

Если не работает senfile и нет возможности сделать mlock, то ваш вариант довольно неплох... но лично я бы его тестировал вместе с вариантом open(O_DIRECT)/read/write из-за того, что он не выдавит кэш и после копирования можно будет работать без заметных задержек.

Murr ★★
()
Ответ на: комментарий от Murr

благодаря что немного просветили

ещё бы мнение Idle услышать ;-)

cvv ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.