Ответ 1
Код проверяет, правильно ли выравниваются адреса для UINT
. Если это так, код копирует с помощью объектов UINT
. Если нет, код копирует с помощью объектов BYTE
.
Тест работает, сначала выполнив побитовое ИЛИ двух адресов. Любой бит, который включен в любом из адресов, будет включен в результат. Затем тест выполняет побитовое И с sizeof(UINT) - 1
. Ожидается, что размер a UINT
является некоторой степенью двух. Тогда размер минус один имеет все нижние бит. Например, если размер 4 или 8, то один меньше, чем в двоичном формате 11 2 или 111 2. Если какой-либо адрес не кратен размеру UINT
, тогда он будет иметь один из этих битов, и тест покажет его. (Как правило, наилучшее выравнивание для целочисленного объекта такое же, как и его размер. Это не обязательно так. Современная реализация этого кода должна использовать _Alignof(UINT) - 1
вместо размера.)
Копирование с объектами UINT
выполняется быстрее, потому что на аппаратном уровне одна команда загрузки или хранения загружает или сохраняет все байты UINT
(вероятно, четыре байта). Процессоры, как правило, копируют быстрее при использовании этих инструкций, чем при использовании в четыре раза больше однобайтовых инструкций загрузки или хранения.
Этот код, конечно, зависит от реализации; он требует поддержки реализации C, которая не является частью базового стандарта C, и зависит от конкретных особенностей процессора, в котором он выполняется.
Более продвинутая реализация memcpy
может содержать дополнительные функции, такие как:
- Если один из адресов выровнен, а другой - нет, используйте специальные инструкции, не привязанные к нагрузке, для загрузки нескольких байтов с одного адреса с регулярными инструкциями магазина на другой адрес.
- Если процессор имеет инструкции с несколькими инструкциями Single Instruction Multiple Data, используйте эти инструкции для загрузки или хранения большого количества байтов (часто 16, возможно, больше) в одной команде.