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 タイプの場合は (より特化されているため) orstd::copyよりも効率的であると予想 されます。イテレータを使用する場合にこれが当てはまるかどうかはコンパイラによって異なりますが、最適化はコンパイラがイテレータを「見抜く」ことができるかどうかに依存します。コンパイラとライブラリの実装によっては、これができない場合があります。memcpymemmove

テスト コードには未定義の動作があることにも注意してください。std::copy(and )を使用するための要件の 1 つはmemcpy、宛先がソース ( [first,last)for std::copy[source,source+n)for memcpy) の範囲内にないことです。ソースと宛先が重複する場合、動作は未定義です。

于 2012-07-30T08:23:07.507 に答える