Я не могу сказать, почему именно соответствующие компиляторы не могут оптимизировать код так, как вы надеетесь оптимизировать его в конкретных случаях.Я предполагаю, что каждый компилятор либо просто не может отследить отношения, установленные memcpy между целевым массивом и исходной памятью (как мы можем видеть, они, кажется, распознают эту связь, по крайней мере, в некоторых случаях), либо у них просто есть какое-то эвристическое сообщениеони решили не использовать его.
В любом случае, поскольку компиляторы, похоже, не ведут себя так, как мы надеемся, когда мы полагаемся на то, что они отслеживают весь массив, мы можем попытаться сделать его более очевиднымкомпилятору, просто выполняя memcpy для каждого элемента.Это , похоже, дает желаемый результат на обоих компиляторах .Обратите внимание, что мне пришлось вручную развернуть инициализацию в bar
и foo
, поскольку в противном случае clang снова сделает копию.
Кроме того, обратите внимание, что в C ++ вы должны использовать std::memcpy
, std::uint64_t
и т. д., поскольку стандартные заголовки не гарантируют также внесения этих имен в глобальное пространство имен (хотя я не знаю ни одной реализации, которая этого не делает).