LINUX.ORG.RU
решено  
hibou

Копирование перекрывающихся участков памяти


0

1

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

Участки перекрываются так:

 1.      |----------|
 2. |----------|
Нужно перенести данные из 1 в 2. Стандартными функциями пользоваться в принципе можно, но это слишком большая надежда, что она всегда будет копировать от начала к концу, а не наоборот.

Я предложил обычный цикл for, тупо скопировать из 1 в 2 побайтно. Коллега говорит, что лучше вычислить кусок до перекрытия, скопировать его стандартной функцией, потом докопировать остальное опять же стандартной функцией. Типа говорит, что так будет быстрее несмотря на усложнение алгоритма.

Действие происходит в ядре Linux. Куски памяти могут быть до 15 Мб.

Как считаете, как будет быстрее? Есть ли еще какой-то путь? Заранее спасибо за участие.


[#]  
>>-----Цитата---->>

Стандартными функциями пользоваться в принципе можно

<<-----Цитата----<<

Это какими?

Можно сделать на ассемблерной вставке. Наверняка быстрее будет. Хотя, чем черт не шутит: gcc -O3 иногда очень даже хорошо оптимизирует.

**** ()
[#] Ответ на: комментарий от hibou 21.12.2011 12:52:40  

Вспомни шутку про идиотов, использовавших memcpy, не читая внимательно мануала. Помнится, какая-то адобовская ненужная поделка из-за этого отличненько сегфолтилась.

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

**** ()
[#] Ответ на: комментарий от Eddy_Em 21.12.2011 12:55:39  

Да циклом-то не хуже можно скопировать.
Но опять же для разных процев можно по разному.
Например 16-байтовыми кусками с помощью xmm.

()
[#] Ответ на: комментарий от Galant 21.12.2011 12:59:21  

У меня такое подозрение (в кодах glibc ковыряться нет желания), что memmove и реализован через ассемблерные архитектурнозависимые инструкции.

**** ()
[#]  
ttnl

Было столько срачей на тему memcpy/memmove, где был ты?

/**
* memmove - Copy one area of memory to another
* @dest: Where to copy to
* @src: Where to copy from
* @count: The size of the area.
*
* Unlike memcpy(), memmove() copes with overlapping areas.
*/
void *memmove(void *dest, const void *src, size_t count)

**** ()
[#]  
Rzhepish

> Действие происходит в ядре Linux. Куски памяти могут быть до 15 Мб.

Весьма вероятно, что вы что-то делаете не так. Какой сценарий?

* ()
[#] Ответ на: комментарий от Eddy_Em 21.12.2011 14:13:13  
ttnl
>>-----Цитата---->>

Кстати, интересно, как будет вести себя memmove, если области перекрываются сильно (т.е. начальная область неперекрытия меньше размера блока).

<<-----Цитата----<<

Нормально будет себя вести. Все кривые случаи в ней предусмотрены. Это стандартная функция.

**** ()
[#] Ответ на: комментарий от Eddy_Em 21.12.2011 13:00:15  

Ты еще и ман не читаешь :) Стандартная ф-ция memmove весьма медленная, т.к. используется третий участок памяти, и копирование for'ом будет быстрее :).

*** ()
[#] Ответ на: комментарий от Jetty 21.12.2011 20:25:59  
>>-----Цитата---->>

Ты еще и ман не читаешь :) Стандартная ф-ция memmove весьма медленная, т.к. используется третий участок памяти, и копирование for'ом будет быстрее :).

<<-----Цитата----<<

4.2 и бан тебе, переводчик хренов.

()
[#] Ответ на: комментарий от Jetty 21.12.2011 20:25:59  
void *memmove(void *dest, const void *src, size_t count)
{
    char *tmp;
    const char *s;

    if (dest <= src) {
        tmp = dest;
        s = src;
        while (count--)
            *tmp++ = *s++;
    } else {
        tmp = dest;
        tmp += count;
        s = src;
        s += count;
        while (count--)
            *--tmp = *--s;
    }
    return dest;
}

Код из ядра linux.

()
[#] Ответ на: комментарий от Galant 21.12.2011 21:07:53  

поясняю: в мане написано "as though"
Сырцы не смотрел, но уверен что там нет третьего участка. Ядро люди не глупей меня делают небось.

()
[#] Ответ на: комментарий от Jetty 21.12.2011 20:25:59  
Waterlaz
>>-----Цитата---->>

Ты еще и ман не читаешь :) Стандартная ф-ция memmove весьма медленная, т.к. используется третий участок памяти, и копирование for'ом будет быстрее :).

<<-----Цитата----<<

Какой нах третий участок? Ты чем ударился?

** ()
[#] Ответ на: комментарий от Jetty 21.12.2011 20:25:59  
Manhunt
>>-----Цитата---->>

Стандартная ф-ция memmove весьма медленная, т.к. используется третий участок памяти, и копирование for'ом будет быстрее

<<-----Цитата----<<

Слов нет. Кто ж нарожал-то вас таких, горе-оптимизаторов? Ты действительно уверен, что код ключевых библиотек написан хуже, чем ты, криворучка for-овая, за 5 минут на коленке нафигачишь?

Покажи, блин, где тут "третий участок памяти":

http://www.mirrorservice.org/sites/ftp.gnu.org/gnu/glibc/glibc-2.14.1.tar.gz/gli...

*** ()
[#] Ответ на: комментарий от Jetty 21.12.2011 22:25:09  
OldFatMan

В выделенном тобой предложении ты не обратил внимания на словосочетание "as though", которое переводится, как "если бы, (как) будто бы, словно, как бы".

Если уж читать man-ы, то внимательно.

# ()
[#] Ответ на: комментарий от Eddy_Em 21.12.2011 12:54:45  
>>-----Цитата---->>

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

<<-----Цитата----<<

есть такие инструкции, rep movsb/rep movsd для копирования блоков, со времен, кажетсяб 486. Но т.к компиляторы ЯВУ таких инструкций не генерируют, а на ассемблере мало кто пишет, инженеры Intel дооптимизировались до того, что обычный mov в цикле, выдаваемый компиляторами, работает быстрее )

* ()
[#] Ответ на: комментарий от Jetty 22.12.2011 0:12:06  
OldFatMan

"...копирование происходит так, как будто бы (как если бы) байты в src сначала копируются в (некоторый) временный массив, который не пересекается ни с src, ни с dst, а затем те же байты копируются из этого временного массива в dst."

"as though" относится ко всей второй части предложения.

Упоминание "двух этапов" тоже воображаемое, как и "временный массив".

# ()
[#] Ответ на: комментарий от Jetty 21.12.2011 20:25:59  
maloi

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

*** ()
[#] Ответ на: комментарий от maloi 22.12.2011 17:35:17  

в моем так же. Но на самом деле так не происходит в умолчательном memmove :). Но есть еще архитектуро спецефические меммувы, которые писаны на асме, а я с асмом не дружу :)

*** ()
[#] Ответ на: комментарий от Jetty 22.12.2011 18:08:27  
hibou

Я вот думаю, а какой смысл вообще копировать через третий буфер? Есть ли этот смысл, если можно просто определить направление копирования, что гораздо быстрее и не требует выделения дополнительной памяти?

***** ()