[英]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::copy
比memcpy
或memmove
(因为它更专用)更有效。 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.