Вы должны проверить код сборки, сгенерированный для вашего кода. То, что вы не хотите, - это чтобы вызов memcpy
генерировал вызов функции memcpy
в стандартной библиотеке - то, что вам нужно, - это повторный вызов наилучшей инструкции ASM для копирования наибольшего объема данных - что-то вроде rep movsq
.
Как этого добиться? Что ж, компилятор оптимизирует вызовы к memcpy
, заменяя его простыми mov
s, пока он знает, сколько данных он должен скопировать. Вы можете увидеть это, если напишите memcpy
с точно определенным (constexpr
) значением. Если компилятор не знает значение, ему придется вернуться к реализации уровня байтов memcpy
- проблема заключается в том, что memcpy
должен учитывать гранулярность в один байт. Он по-прежнему будет перемещаться по 128 бит за раз, но после каждого 128b он должен будет проверить, достаточно ли у него данных для копирования как 128b или он должен вернуться к 64 битам, затем к 32 и 8 (я думаю, что 16 может быть неоптимальным во всяком случае, но я не знаю точно).
Так что вы можете либо memcpy
сообщить, какой размер ваших данных с помощью константных выражений, которые компилятор может оптимизировать. Таким образом, вызов memcpy
не выполняется. Чего вы не хотите, так это передавать memcpy
переменную, которая будет известна только во время выполнения. Это приводит к вызову функции и множеству тестов для проверки лучшей инструкции копирования. Иногда простой цикл for лучше, чем memcpy
по этой причине (исключая один вызов функции). И что вы действительно не хотите - это передача memcpy
нечетного числа байтов для копирования.