Re[5]: проблема с memcpy на Linux
От: Блудов Павел Россия  
Дата: 01.06.24 11:06
Оценка: 3 (2) +2
Здравствуйте, maks1180, Вы писали:

M>Почему он значения dst зависит вперёд или назад копировать, я не пойму...


memcpy копирует байты. Желание ускорить копирование вполне естественно.
Одна из очевидных оптимизаций — копировать байты параллельно. Лет двадцать назад я посмотрел под отладчиком как выглядит код зануления структуры в памяти. Вместо rep stosb я увидел одну MMX инструкцию, одну инструкцию для математического сопроцесора, одну AVX инструкцию и пару обычных. Зачем такие сложности? А затем, что все эти инструкции процессор обрабатывает параллельно. Аналогично с копированием. Если копирование можно распараллелить, то его можно ускорить. При этом порядок, в котором байты попадают из src в dst в общем виде будет не определён.
проблема с memcpy на Linux
От: maks1180  
Дата: 29.05.24 19:23
Оценка: :))) :)
вызываю memcpy(dst, src, len), где src=dst+58, len=137. dst всегда кратен 16.
Т.е. диапазоны перекрываются, но так как src больше чем dst, поэтому я думал проблем ну будет.
Но вышла проблема, причём самое интересное, что проявляется переодически.
Заметил, что когда dst заканчивается на D0,E0,F0 проблема есть. Т.е. 3 из 16 раз.

Пытался посмотреть исходники memcpy, понял что он копирует вперёд (т.е. увеличивая поинтеры), но я не понял почему оно зависит от адреса dst и почему вообще проблема существует если идёт вперёд при копировании.
===============================================
(реклама, удалена модератором)
Отредактировано 29.05.2024 20:36 maks1180 . Предыдущая версия . Еще …
Отредактировано 29.05.2024 20:28 maks1180 . Предыдущая версия .
Re: проблема с memcpy на Linux
От: Слава  
Дата: 30.05.24 01:20
Оценка: +4
Здравствуйте, maks1180, Вы писали:

M>Пытался посмотреть исходники memcpy, понял что он копирует вперёд (т.е. увеличивая поинтеры), но я не понял почему оно зависит от адреса dst и почему вообще проблема существует если идёт вперёд при копировании.


Может стоить взять memmove? И не выдумывать вот это вот всё, просмотр отладчиком как работает rep movsb
Re[3]: проблема с memcpy на Linux
От: kov_serg Россия  
Дата: 29.05.24 21:00
Оценка: +3
Здравствуйте, maks1180, Вы писали:

_>>Замените на std::memmove


M>Это понятно, просто хотел разобраться как работает memcpy

А какой смысл, если оно меняется с платформой и компилятором да еще и от фазы луны может зависеть?
Если оно UB то чудеса могут быть такие что хоть обсмотрись исходников, грабли которые компилятор разложит там не видно.
Re[3]: проблема с memcpy на Linux
От: vsb Казахстан  
Дата: 29.05.24 20:45
Оценка: +2
Здравствуйте, maks1180, Вы писали:

M>Это понятно, просто хотел разобраться как работает memcpy


Надо смотреть не исходники, а скомпилированный код. Компилятор может заменить вызов memcpy на цикл, например. Также memcpy может быть в куче вариантов и какой там скомпилируется — не разберёшься. В общем надо отладчиком лезть и в дизассемблер смотреть, благо memcpy штука небольшая.
Re[5]: проблема с memcpy на Linux
От: kov_serg Россия  
Дата: 29.05.24 22:11
Оценка: 13 (1)
Здравствуйте, maks1180, Вы писали:

M>Смысл разобраться, что-бы понимать что под капотом memcpy твориться, может что нового для себя подчерпнуть.

https://www.youtube.com/watch?v=mmnWSkwF7KQ
Re: проблема с memcpy на Linux
От: kov_serg Россия  
Дата: 29.05.24 19:39
Оценка: +1
Здравствуйте, maks1180, Вы писали:

M>вызываю memcpy(dst, src, len), где src=dst+90, len=137. dst всегда кратен 16.

M>Т.е. диапазоны перекрываются, но так как src больше чем dst, поэтому я думал проблем ну будет.
M>Но вышла проблема, причём самое интересное, что проявляется переодически.
M>Заметил, что когда dst заканчивает на B0,С0,D0 проблема есть. Т.е. 3 из 16 раз.

M>Пытался посмотреть исходники memcpy, понял что он копирует вперёд (т.е. увеличивая поинтеры), но возможно кусочек начала копирует в конце поэтому и проблема,

M>но я не понял почему оно зависит от адреса dst.

https://en.cppreference.com/w/cpp/string/byte/memcpy

If the objects overlap, the behavior is undefined.

Замените на std::memmove
Re[5]: проблема с memcpy на Linux
От: пффф  
Дата: 31.05.24 23:49
Оценка: +1
Здравствуйте, maks1180, Вы писали:

M>Смысл разобраться, что-бы понимать что под капотом memcpy твориться, может что нового для себя подчерпнуть.


Что за бред? Под капотом там может творится всё что угодно.


M>Кажется простая функция, а нарвался на неприятности, обидно что в релизе клиенты нашли.


Функция простая, просто не надо её использовать для того, для чего она не предназначена, и будет тебе счастье.


M>По анализам полученных данных после memcpy, подходит версия, что он иногда копирует от конца к началу данные, а не вперёд, вот тогда и начинаются проблемы.

M>Почему он значения dst зависит вперёд или назад копировать, я не пойму...

Может, просто почитать стандарт, и зазубрить, что memcpy даёт UB при перекрытии src и dst?
Re: проблема с memcpy на Linux
От: ononim  
Дата: 05.06.24 09:04
Оценка: +1
M>Пытался посмотреть исходники memcpy, понял что он копирует вперёд (т.е. увеличивая поинтеры), но я не понял почему оно зависит от адреса dst и почему вообще проблема существует если идёт вперёд при копировании.
Ты наверное нашел не те исходники, их много, своя под каждую платформу, иногда своя под каждые возможные фичи процессора, вот например одна из возможных (выбираемых в рантайме) реализаций https://github.com/bminor/glibc/blob/master/sysdeps/x86_64/multiarch/memmove-avx512-no-vzeroupper.S
И это только вариации для x86-64
Как много веселых ребят, и все делают велосипед...
Отредактировано 05.06.2024 9:11 ononim . Предыдущая версия .
Re[2]: проблема с memcpy на Linux
От: maks1180  
Дата: 29.05.24 20:06
Оценка:
_>Замените на std::memmove

Это понятно, просто хотел разобраться как работает memcpy
===============================================
(реклама, удалена модератором)
Re[4]: проблема с memcpy на Linux
От: maks1180  
Дата: 29.05.24 21:13
Оценка:
_>А какой смысл, если оно меняется с платформой и компилятором да еще и от фазы луны может зависеть?
_>Если оно UB то чудеса могут быть такие что хоть обсмотрись исходников, грабли которые компилятор разложит там не видно.

Смысл разобраться, что-бы понимать что под капотом memcpy твориться, может что нового для себя подчерпнуть.
Кажется простая функция, а нарвался на неприятности, обидно что в релизе клиенты нашли.
По анализам полученных данных после memcpy, подходит версия, что он иногда копирует от конца к началу данные, а не вперёд, вот тогда и начинаются проблемы.
Почему он значения dst зависит вперёд или назад копировать, я не пойму...
===============================================
(реклама, удалена модератором)
Re: проблема с memcpy на Linux
От: Pzz Россия https://github.com/alexpevzner
Дата: 05.06.24 11:03
Оценка:
Здравствуйте, maks1180, Вы писали:

M>вызываю memcpy(dst, src, len), где src=dst+58, len=137. dst всегда кратен 16.

M>Т.е. диапазоны перекрываются, но так как src больше чем dst, поэтому я думал проблем ну будет.

Это, конечно, недоработка со стороны разработчиков компиляторов C/C++. Undefined Behaviour зачастую сходит с рук незамеченным. Должно было бы сделано так: за каждый случай UB, прошедший review и тестирование у кого-нибудь из причастных на кухне убегает молоко или протекает унитаз.
Re[6]: проблема с memcpy на Linux
От: Pzz Россия https://github.com/alexpevzner
Дата: 05.06.24 11:05
Оценка:
Здравствуйте, пффф, Вы писали:

П>Может, просто почитать стандарт, и зазубрить, что memcpy даёт UB при перекрытии src и dst?


Интересно, а кто-нибудь из присутствующих читал стандарт? Вот прям именно стандарт, а не его пересказ человеческими словами?
Re[7]: проблема с memcpy на Linux
От: пффф  
Дата: 05.06.24 12:07
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Здравствуйте, пффф, Вы писали:


П>>Может, просто почитать стандарт, и зазубрить, что memcpy даёт UB при перекрытии src и dst?


Pzz>Интересно, а кто-нибудь из присутствующих читал стандарт? Вот прям именно стандарт, а не его пересказ человеческими словами?


https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf

7.24.2 Copying functions
7.24.2.1 The memcpy function
Synopsis
1 #include <string.h>
void *memcpy(void * restrict s1,
const void * restrict s2,
size_t n);
Description
2 The memcpy function copies n characters from the object pointed to by s2 into the
object pointed to by s1. If copying takes place between objects that overlap, the behavior
is undefined
.
Returns
3 The memcpy function returns the value of s1



Извини, не UB, а the behavior is undefined

ЗЫ Больше стандартов тут — https://stackoverflow.com/questions/81656/where-do-i-find-the-current-c-or-c-standard-documents
Re[8]: проблема с memcpy на Linux
От: Pzz Россия https://github.com/alexpevzner
Дата: 05.06.24 13:28
Оценка:
Здравствуйте, пффф, Вы писали:

Pzz>>Интересно, а кто-нибудь из присутствующих читал стандарт? Вот прям именно стандарт, а не его пересказ человеческими словами?


П>https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf


Мне правда было интересно, читают ли в среднем люди стандарты, или находят их на интернете в "переваренном" виде.

П>Извини, не UB, а the behavior is undefined


А это не одно и то же?
Re[9]: проблема с memcpy на Linux
От: пффф  
Дата: 05.06.24 13:54
Оценка:
Здравствуйте, Pzz, Вы писали:

П>>https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf


Pzz>Мне правда было интересно, читают ли в среднем люди стандарты, или находят их на интернете в "переваренном" виде.


В среднем — скорее нет. Я тоже редко заглядываю


П>>Извини, не UB, а the behavior is undefined


Pzz>А это не одно и то же?


Неопределенное поведение, или поведение не определено? С точки зрения обычного человека, оно конечно одно и то же, но я давно понял, что стандарты, особенно плюсовые, пишут рептилоиды, так что не факт.
Re[10]: проблема с memcpy на Linux
От: Pzz Россия https://github.com/alexpevzner
Дата: 05.06.24 14:02
Оценка:
Здравствуйте, пффф, Вы писали:

Pzz>>А это не одно и то же?


П>Неопределенное поведение, или поведение не определено? С точки зрения обычного человека, оно конечно одно и то же, но я давно понял, что стандарты, особенно плюсовые, пишут рептилоиды, так что не факт.


Там же вроде есть термины implementation-defined/unspecified/undefined behaviour, и они прям термины-термины, как MUST/MAY/SHOULD в RFC.

Так что behaviour undefined вроде как должно быть то же самое, что undefined behaviour, не?

Про рептилоидов согласен

Что интересно, сетевые RFC на заре цивилизации писали люди, и их прям можно было читать, а потом людей вытеснили рептилоиды, и читать их стало сложно.
Re[3]: проблема с memcpy на Linux
От: Worminator X Россия #StandWithPalestine 🖤🤍💚
Дата: 06.07.24 02:14
Оценка:
Здравствуйте, maks1180, Вы писали:

M>Это понятно, просто хотел разобраться как работает memcpy


Зависит от реализации конкретного компилятора, как понимаю, а он использует какие-то функции из ОС (WinAPI, системные вызовы POSIX и др.).
Для перекрывающихся областей всегда необходимо использовать memmove, оно для того и придумано.
Как запру я тебя за железный замок, за дубовую дверь окованную,
Чтоб свету божьего ты не видела, мое имя честное не порочила…
М. Лермонтов. Песня про царя Ивана Васильевича, молодого опричника и удалого купца Калашникова
Re[9]: проблема с memcpy на Linux
От: Worminator X Россия #StandWithPalestine 🖤🤍💚
Дата: 06.07.24 02:16
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Мне правда было интересно, читают ли в среднем люди стандарты, или находят их на интернете в "переваренном" виде.


Многие стандарты платные. Слишком много чести кормить тунеядцев и социальных паразитов.
Как запру я тебя за железный замок, за дубовую дверь окованную,
Чтоб свету божьего ты не видела, мое имя честное не порочила…
М. Лермонтов. Песня про царя Ивана Васильевича, молодого опричника и удалого купца Калашникова
Re[3]: проблема с memcpy на Linux
От: graniar  
Дата: 13.07.24 19:11
Оценка:
Здравствуйте, maks1180, Вы писали:

_>>Замените на std::memmove

M>Это понятно, просто хотел разобраться как работает memcpy

Тогда это не "проблема с memcpy", а детали реализации.
И в мануале прямо указано, что области памяти не должны перекрываться.

man memcpy

The memcpy() function copies n bytes from memory area src to memory area dest. The memory areas must not overlap. Use memmove(3) if the memory areas do overlap.

Re[2]: проблема с memcpy на Linux
От: graniar  
Дата: 13.07.24 19:17
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Это, конечно, недоработка со стороны разработчиков компиляторов C/C++.


Непонятно, почему это вообще должно парить разработчиков компилятора.
Это документированное поведение функции memcpy. Если некто неправильно ее использует, это его проблемы.
А то может вообще требовать от компилятора обнаруживать все потенциальные баги?
Тогда это уже не C/C++ надо, а доказательное программирование.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.