Reputation: 948
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
Upvotes: 2
Views: 508
Reputation: 153957
The "answer" in the thread you post is wrong. Generally, I would expect
std::copy
to be more efficient than memcpy
or memmove
(because it
is 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
(and memcpy
) is that the
destination is not in the range of the source ([first,last)
for
std::copy
, [source,source+n)
for memcpy
). If the source and the
destination overlap, the behavior is undefined.
Upvotes: 1