Re: Deprecate the use of plain pointers as standard container iterators
4zumanga@gmail.com wrote:
Peter Dimov wrote:
Nicola Musatti wrote:
Hallo,
I belive that the use of plain pointers as iterator types for standard
library containers should be deprecated, because it limits genericity
and portability.
It also increases performance and presents more opportunities for
optimization.
Can you provide an example of this on a modern optimising compiler, ie
where the optimiser does better with
int* i;
than it does with:
struct iterator { int* i };
About a year ago I spent quite a lot of time investigating if g++ 4 has
any problems when vector iterators are wrapped in a class, and couldn't
produce an example where the resulting assembler wasn't the same.
If you consider MSVC 7.1 a modern compiler:
#include <vector>
unsigned char w1[ 1024 ];
unsigned char w2[ 1024 ];
std::vector<unsigned char> v1( 1024 );
std::vector<unsigned char> v2( 1024 );
template<class It, class It2> void copy2( It first, It last, It2 out )
{
for( ; first != last; ++first, ++out )
{
*out = *first;
}
}
int main()
{
copy2( w1, w1 + 1024, w2 );
copy2( v1.begin(), v1.end(), v2.begin() );
}
Here's the disassembly. The first line is replaced with the intrinsic
inline expansion of memcpy (rep movsd), the second results in a loop
that copies byte by byte. It's not even unrolled.
_main PROC NEAR ; COMDAT
; 19 : copy2( w1, w1 + 1024, w2 );
; 20 : copy2( v1.begin(), v1.end(), v2.begin() );
mov eax, DWORD PTR ?v1@@3V?$vector@EV?$allocator@E@std@@@std@@A+4
push esi
push edi
mov ecx, 256 ; 00000100H
mov esi, OFFSET FLAT:?w1@@3PAEA ; w1
mov edi, OFFSET FLAT:?w2@@3PAEA ; w2
rep movsd
mov esi, DWORD PTR ?v1@@3V?$vector@EV?$allocator@E@std@@@std@@A+8
cmp eax, esi
mov ecx, DWORD PTR ?v2@@3V?$vector@EV?$allocator@E@std@@@std@@A+4
je SHORT $L7165
$L7144:
mov dl, BYTE PTR [eax]
inc eax
mov BYTE PTR [ecx], dl
inc ecx
cmp eax, esi
jne SHORT $L7144
$L7165:
pop edi
; 21 : }
xor eax, eax
pop esi
ret 0
_main ENDP
This example isn't fair, though, since 1024 is clearly visible to the
compiler and the vector size is not. But even if I level out the field
a bit:
extern size_t N;
int main()
{
copy2( w1, w1 + N, w2 );
copy2( v1.begin(), v1.end(), v2.begin() );
}
the first line is still a memcpy:
; 21 : copy2( w1, w1 + N, w2 );
mov ecx, DWORD PTR ?N@@3IA ; N
lea ecx, DWORD PTR ?w1@@3PAEA[ecx]
cmp ecx, OFFSET FLAT:?w1@@3PAEA ; w1
push esi
je SHORT $L7054
sub ecx, OFFSET FLAT:?w1@@3PAEA ; w1
mov eax, ecx
push edi
shr ecx, 2
mov esi, OFFSET FLAT:?w1@@3PAEA ; w1
mov edi, OFFSET FLAT:?w2@@3PAEA ; w2
rep movsd
mov ecx, eax
and ecx, 3
rep movsb
pop edi
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]