According to some post here ( Efficiency of std::copy vs memcpy , ) std::copy is supposed to be reduce to memcpy/memmove on a pod type. i am trying to test that but i cant replicate the result.
I am using visual studio 2010 and I tried all optimization levels
struct pod_
{
unsigned int v1 ,v2 ,v3 ;
} ;
typedef pod_ T ;
static_assert(std::is_pod<pod_>::value, "Struct must be a POD type");
const unsigned int size = 20*1024*1024 / sizeof(T);
std::vector<T> buffer1(size) ;
std::vector<T> buffer2((size)) ;
And i tried this :
std::copy(buffer1.begin(),buffer1.end(),&buffer2[0]);
0030109C mov esi,dword ptr [esp+14h]
003010A0 mov ecx,dword ptr [esp+18h]
003010A4 mov edi,dword ptr [esp+24h]
003010A8 mov eax,esi
003010AA cmp esi,ecx
003010AC je main+8Eh (3010CEh)
003010AE mov edx,edi
003010B0 sub edx,esi
003010B2 mov ebx,dword ptr [eax]
003010B4 mov dword ptr [edx+eax],ebx
003010B7 mov ebx,dword ptr [eax+4]
003010BA mov dword ptr [edx+eax+4],ebx
003010BE mov ebx,dword ptr [eax+8]
003010C1 mov dword ptr [edx+eax+8],ebx
003010C5 add eax,0Ch
003010C8 cmp eax,ecx
003010CA jne main+72h (3010B2h)
003010CC xor ebx,ebx
casting to a primitive type seems to work.
std::copy((char *)&buffer1[0],(char *)&buffer1[buffer1.size() - 1],(char *)&buffer2[0]);
003010CE sub ecx,esi
003010D0 mov eax,2AAAAAABh
003010D5 imul ecx
003010D7 sar edx,1
003010D9 mov eax,edx
003010DB shr eax,1Fh
003010DE add eax,edx
003010E0 lea eax,[eax+eax*2]
003010E3 lea ecx,[eax*4-0Ch]
003010EA push ecx
003010EB push esi
003010EC push edi
003010ED call dword ptr [__imp__memmove (3020B0h)]
003010F3 add esp,0Ch
The “answer” in the thread you post is wrong. Generally, I would expect
std::copyto be more efficient thanmemcpyormemmove(because itis more specialized) for POD types. Whether this is the case when using
iterators depends on the compiler, but any optimization does depend on
the compiler being able to “see through” the iterators. Depending on
the compiler and the implementation of the library, this may not be
possible.
Note too that your test code has undefined behavior. One of the
requirements for using
std::copy(andmemcpy) is that thedestination is not in the range of the source (
[first,last)forstd::copy,[source,source+n)formemcpy). If the source and thedestination overlap, the behavior is undefined.