This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
[PATCH], correction (was Re: [Patch] Step2: ...)
On Tue, Jun 24, 2003 at 12:57:58PM -0700, Nathan Myers wrote:
> I ran another benchmark, attached below, on several compilers
> on P3 and Opteron. All builds are -O2.
I have been analyzing the results, particularly the anomalous
Opteron result.
> P3 1.4GHz.
> ----------
> ...
> Mainline w/ inlines
> stdio (unlocked): 1.85u 0.10s 2.65r
> streambuf: 2.10u 0.09s 2.79r
It appears this difference is a result of loop unrolling on
behalf of stdio, but not streambuf.
> Opteron 1.4GHz
> ---------------
> ...
> Mainline w/inlines
> stdio (unlocked): 1.64u 0.34s 3.52r
> streambuf: 3.08u 0.33s 4.91r [WRONG]
This difference is a measurement error. It turns out that PCH
retained a copy of the old version of the header file I had
patched. The correct result (cue sigh of relief here) is
stdio (unlocked): 1.65u 0.34s 2.91r
streambuf: 1.74u 0.35s 2.99r
Note that the code used for this result is not exactly the same
as for the previous measurements. While investigating, I added
annotations __builtin_expect to the inlines. Patch below.
Nathan Myers
ncm-nospam@cantrip.org
Index: include/bits/streambuf.tcc
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/include/bits/streambuf.tcc,v
retrieving revision 1.43
diff -u -u -r1.43 streambuf.tcc
--- include/bits/streambuf.tcc 24 Jun 2003 13:48:09 -0000 1.43
+++ include/bits/streambuf.tcc 25 Jun 2003 05:18:08 -0000
@@ -40,72 +40,6 @@
namespace std
{
template<typename _CharT, typename _Traits>
- typename basic_streambuf<_CharT, _Traits>::int_type
- basic_streambuf<_CharT, _Traits>::
- sbumpc()
- {
- int_type __ret;
- if (this->gptr() < this->egptr())
- {
- __ret = traits_type::to_int_type(*this->gptr());
- this->gbump(1);
- }
- else
- __ret = this->uflow();
- return __ret;
- }
-
- template<typename _CharT, typename _Traits>
- typename basic_streambuf<_CharT, _Traits>::int_type
- basic_streambuf<_CharT, _Traits>::
- sputbackc(char_type __c)
- {
- int_type __ret;
- const bool __testpos = this->eback() < this->gptr();
- if (!__testpos || !traits_type::eq(__c, this->gptr()[-1]))
- __ret = this->pbackfail(traits_type::to_int_type(__c));
- else
- {
- this->gbump(-1);
- __ret = traits_type::to_int_type(*this->gptr());
- }
- return __ret;
- }
-
- template<typename _CharT, typename _Traits>
- typename basic_streambuf<_CharT, _Traits>::int_type
- basic_streambuf<_CharT, _Traits>::
- sungetc()
- {
- int_type __ret;
- if (this->eback() < this->gptr())
- {
- this->gbump(-1);
- __ret = traits_type::to_int_type(*this->gptr());
- }
- else
- __ret = this->pbackfail();
- return __ret;
- }
-
- template<typename _CharT, typename _Traits>
- typename basic_streambuf<_CharT, _Traits>::int_type
- basic_streambuf<_CharT, _Traits>::
- sputc(char_type __c)
- {
- int_type __ret;
- if (this->pptr() < this->epptr())
- {
- *this->pptr() = __c;
- this->pbump(1);
- __ret = traits_type::to_int_type(__c);
- }
- else
- __ret = this->overflow(traits_type::to_int_type(__c));
- return __ret;
- }
-
- template<typename _CharT, typename _Traits>
streamsize
basic_streambuf<_CharT, _Traits>::
xsgetn(char_type* __s, streamsize __n)
Index: include/std/std_streambuf.h
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/include/std/std_streambuf.h,v
retrieving revision 1.35
diff -u -u -r1.35 std_streambuf.h
--- include/std/std_streambuf.h 24 Jun 2003 13:48:09 -0000 1.35
+++ include/std/std_streambuf.h 25 Jun 2003 05:18:08 -0000
@@ -287,7 +287,8 @@
snextc()
{
int_type __ret = traits_type::eof();
- if (!traits_type::eq_int_type(this->sbumpc(), __ret))
+ if (__builtin_expect(!traits_type::eq_int_type(this->sbumpc(),
+ __ret),true))
__ret = this->sgetc();
return __ret;
}
@@ -301,7 +302,19 @@
* @c uflow().
*/
int_type
- sbumpc();
+ sbumpc()
+ {
+ int_type __ret;
+ if (__builtin_expect(this->gptr() < this->egptr(), true))
+ {
+ __ret = traits_type::to_int_type(*this->gptr());
+ this->gbump(1);
+ }
+ else
+ __ret = this->uflow();
+ return __ret;
+ }
+
/**
* @brief Getting the next character.
@@ -315,7 +328,7 @@
sgetc()
{
int_type __ret;
- if (this->gptr() < this->egptr())
+ if (__builtin_expect(this->gptr() < this->egptr(), true))
__ret = traits_type::to_int_type(*this->gptr());
else
__ret = this->underflow();
@@ -345,7 +358,20 @@
* fetched from the input stream will be @a c.
*/
int_type
- sputbackc(char_type __c);
+ sputbackc(char_type __c)
+ {
+ int_type __ret;
+ const bool __testpos = this->eback() < this->gptr();
+ if (__builtin_expect(!__testpos ||
+ !traits_type::eq(__c, this->gptr()[-1]),false))
+ __ret = this->pbackfail(traits_type::to_int_type(__c));
+ else
+ {
+ this->gbump(-1);
+ __ret = traits_type::to_int_type(*this->gptr());
+ }
+ return __ret;
+ }
/**
* @brief Moving backwards in the input stream.
@@ -357,7 +383,18 @@
* "gotten".
*/
int_type
- sungetc();
+ sungetc()
+ {
+ int_type __ret;
+ if (__builtin_expect(this->eback() < this->gptr(), true))
+ {
+ this->gbump(-1);
+ __ret = traits_type::to_int_type(*this->gptr());
+ }
+ else
+ __ret = this->pbackfail();
+ return __ret;
+ }
// [27.5.2.2.5] put area
/**
@@ -373,7 +410,19 @@
* position is not available, returns @c overflow(c).
*/
int_type
- sputc(char_type __c);
+ sputc(char_type __c)
+ {
+ int_type __ret;
+ if (__builtin_expect(this->pptr() < this->epptr(), true))
+ {
+ *this->pptr() = __c;
+ this->pbump(1);
+ __ret = traits_type::to_int_type(__c);
+ }
+ else
+ __ret = this->overflow(traits_type::to_int_type(__c));
+ return __ret;
+ }
/**
* @brief Entry point for all single-character output functions.