2

根据这里的一些帖子(std::copy 与 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 
4

1 回答 1

1

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

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

于 2012-07-30T08:23:07.507 回答