2012-07-30 75 views
2

根据这里的一些帖子(Efficiency of std::copy vs memcpy),std :: copy应该被压缩到一个pod类型的memcpy/memmove。我试图测试,但我不能复制结果。编译器将std :: copy复制到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 
+3

条件是,标准库实现者不屑于优化这一点。 ;)虽然可以使用快速'std :: is_pod '标签分发来完成。 – Xeo 2012-07-30 05:45:34

+2

你没有演员试试吗? ('buffer.begin()'与'&buffer [0]'不一样)。 – 2012-07-30 05:49:08

+3

'std :: is_trivially_copyable'是C++ 11的标准。 – 2012-07-30 06:08:16

回答

1

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

还要注意你的测试代码有未定义的行为。一个用于使用std::copy(和memcpy)的 要求之一是 目的地不是在源范围([first,last)std::copy[source,source+n)memcpy)。如果源和目标重叠,则行为不确定。

+0

buffer1和buffer2不同,源/目的地将如何重叠? – GreyGeek 2012-07-30 13:22:48

+0

@GreyGeek对不起,我刚看到'buffer'(和'memmove'的引用,这表明有重叠)。 – 2012-07-30 15:09:42

相关问题