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

时间:2012-07-30 05:43:24

标签: c++ visual-c++

根据这里的一些帖子(Efficiency of std::copy vs memcpy,)std :: copy应该在pod类型上减少为memcpy / memmove。我试图测试,但我不能复制结果。

我正在使用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)) ;

我试过这个:

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  

转换为原始类型似乎有效。

    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 

1 个答案:

答案 0 :(得分:1)

您发布的帖子中的“答案”是错误的。一般来说,我希望 std::copymemcpymemmove更有效率(因为它 POD类型更专业化。使用时是否属于这种情况 迭代器取决于编译器,但任何优化都依赖于 编译器能够“透视”迭代器。取决于 编译器和库的实现,这可能不是 可能的。

另请注意,您的测试代码具有未定义的行为。其中一个 使用std::copy(和memcpy)的要求是 目的地不在来源范围内([first,last)为 对于std::copy[source,source+n)memcpy。如果来源和 目标重叠,行为未定义。