[Patch] Batch of basic_string correctness and performance work

Gawain Bolton gp.bolton@computer.org
Tue Oct 26 20:38:00 GMT 2004


Paolo Carlini wrote:

> Gawain Bolton wrote:
>
>> Hi Paolo,
>>
>> I am seriously worried about performance improvements obtained by 
>> inlining functions.  I'm not disputing the performance measurements 
>> you made below, but this type of test is very much contrived I'm sure 
>> you'll agree.
>
>
> Which "type of test"? I'm sure you don't really think I have only 
> measured and tested and so on, only that couple of testcases in the 
> performance testsuite...

The type of contrived performance testing I'm referring to is the 
21_strings/string_append.cc test where you have a for loop executed 10 
000 000.

>
> Also, more important perhaps, the reason why those functions are 
> inlined is because are small, much smaller than before, and reserve is 
> still out of line. I cannot believe that seriously you don't want to 
> inline this
>
>  void
>  push_back(_CharT __c)
>  {
>    const size_type __len = 1 + this->size();
>    if (__len > this->capacity() || _M_rep()->_M_is_shared())
>      this->reserve(__len);
>    traits_type::assign(_M_data()[this->size()], __c);
>    _M_rep()->_M_set_length_and_sharable(__len);
>  }
>
> which basically is a conditional and 4-5 assignments (+ reserve 
> non-inline) and now is intrinsically 4 times faster.

Yes this is exactly the type of code I'm against inlining.  It contains 
2 tests which will never benefit from branch prediction, which for 
modern CPUs is a major handicap.

Also, this function has a non-negligeable amount of instructions.  These 
additional instructions will impact the CPU's code cache.

>
> As for the sizes, sometimes are slightly smaller, sometimes slightly 
> bigger and in any case we are talking about differences of order << 1% 
> in the static stripped executable. For instance, string_append.cc, 
> that basically only uses basic_string, is less than 0.5% bigger.

Please, let's look at the difference number in terms of octets or 
instructions involved.   Looking at a percentage increase is silly as it 
depends on the application.  Furthermore, looking at the total size of a 
statically linked executable drastically underestimates the size increase.

>
> That said, all those append (and operator+=), in the present form 
> perform much better anyway, also if not-inlined (see, f.i., 
> append(const _CharT*, size_type) or, better example, append(const 
> basic_string&, size_type, size_type), which I purposedly kept 
> off-line), therefore, please provide a little bit of evidence that one 
> of your applications would take advantage from moving the functions 
> out of line and I will happily do that!

Evidence?  How about "Optimizing Pixomatic for Modern x86 Processors: 
Part III" in DDJ, October 2004 (http://www.ddj.com/articles/2004/0410) 
which clearly states the non-obvious effect branch prediction has on 
performance.  Although the article is Pentium specific, the principles 
of branch prediction are equally applicable to superscalar processor 
architectures in general.

I think that perhaps libstdc++ developers need a guideline on inlining.  
Something like: "No functions containing more than two C++ statements 
shall be inlined." is a suggestion.

And yes of course template functions and template based classes are 
exceptions to the rule.

Cheers,


Gawain




More information about the Libstdc++ mailing list