简体   繁体   English

编译器将std :: copy缩减为memcpy(memmove)的条件是什么

[英]What are the condition for the compiler to reduce std::copy to memcpy (memmove)

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. 根据此处的一些文章( std :: copy vs memcpy的效率 ),std :: copy应该在pod类型上减少为memcpy / memmove。 i am trying to test that but i cant replicate the result. 我正在尝试测试,但我无法复制结果。

I am using visual studio 2010 and I tried all optimization levels 我正在使用Visual Studio 2010,并且尝试了所有优化级别

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::copy to be more efficient than memcpy or memmove (because it is more specialized) for POD types. 通常,对于POD类型,我希望std::copymemcpymemmove (因为它更专用)更有效。 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 ). 使用std::copy (和memcpy )的要求之一是目标不在源的范围内( std::copy [first,last) ,对于memcpy [source,source+n) )。 If the source and the destination overlap, the behavior is undefined. 如果源和目标重叠,则行为是不确定的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM