Какой из них использовать - memmove() или memcpy() - когда буферы не перекрываются?
Использование memcpy()
, когда перекрытие источника и адресата может привести к поведению undefined - в этих случаях может использоваться только memmove()
.
Но что, если я точно знаю, что буферы не перекрываются - есть ли причина использовать специально memcpy()
или специально memmove()
? Что я должен использовать и почему?
Ответы
Ответ 1
Предполагая, что разработчик sane library, memcpy
всегда будет как минимум с memmove
. Однако на большинстве платформ разница будет минимальной, и на многих платформах memcpy
является просто псевдонимом для memmove
для поддержки устаревшего кода, который (неправильно) вызывает memcpy
на перекрывающихся буферах.
Оба memcpy
и memmove
должны быть записаны, чтобы использовать преимущества самых быстрых загрузок и хранилищ, доступных на платформе.
Чтобы ответить на ваш вопрос: вы должны использовать тот, который семантически корректен. Если вы можете гарантировать, что буферы не перекрываются, вы должны использовать memcpy
. Если вы не можете гарантировать, что буферы не перекрываются, вы должны использовать memmove
.
Ответ 2
memcpy()
не имеет специальной обработки для перекрывающихся буферов, поэтому ему не хватает некоторых проверок, поэтому он быстрее, чем memmove()
.
Также на некоторых архитектурах memcpy()
может извлечь выгоду из использования инструкций CPU для перемещения блоков памяти - то, что memmove()
не может использовать.
Ответ 3
Если вам интересно, что будет работать лучше, вам нужно протестировать его на целевой платформе. Ничто в стандарте не определяет, как выполняются функции, и, хотя может показаться логичным, что не проверять memcpy
будет быстрее, это отнюдь не определенность.
Вполне возможно, хотя и маловероятно, что человек, который написал memmove
для вашего конкретного компилятора, был сертифицированным гением, а бедная душа, которая получила работу по написанию memcpy
, была деревенским идиотом: -)
Хотя на самом деле мне трудно представить, что memmove
может быть быстрее, чем memcpy
, я не обесцениваю эту возможность. Измерьте, не угадайте.
Ответ 4
На некоторой платформе ARM, над которой работает immove, memmove был в 3 раза быстрее, чем memcpy для короткой нераспределенной нагрузки. Поскольку memcpy и memmove являются единственным действительно переносимым механизмом для тиражирования, вы бы подумали, что это будет некоторая проверка компилятором, прежде чем пытаться использовать NEON для этого.