This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PATCH: Improve efficiency (as measured by system calls made)


I posted this back in June and it has been in my mainline tree since
that time.  It has not shown a regression with the test suite on
*-*-freebsd* (I also tested Solaris at one time).  Does anyone know of
a port or a configuration that would break with this patch or (more
likely) a test case not in the suite that it might break?

I think I may have been given approval to install it if it didn't
break anything way back then, but I would like any comments.

With this patch, I believe that we still have complete buffer
synchronization between C stdio and C++ iostream.  We just make (in
some cases, far) fewer write system calls to sync to the disk/physical
copy than without the patch (however, I think we still make all the
required write calls when streams are tied, line-buffered etc).  This
patch can improve performance of IO test cases without having to add
std::ios::sync_with_stdio ().

	* include/bits/fstream.tcc (basic_filebuf::_M_really_overflow):
	Do not sync() while handling overflow.  The goal is to ensure
	that there is synchronization between C stdio and C++ iostream
	buffers not the stronger post-condition imposed by sync().

Index: include/bits/fstream.tcc
===================================================================
RCS file: /cvs/gcc/egcs/libstdc++-v3/include/bits/fstream.tcc,v
retrieving revision 1.17
diff -c -r1.17 fstream.tcc
*** fstream.tcc	2001/10/29 19:29:29	1.17
--- fstream.tcc	2001/11/16 21:00:55
***************
*** 421,427 ****
  
  	  // NB: Need this so that external byte sequence reflects
  	  // internal buffer.
! 	  _M_file->sync();
  	  if (__len == __plen)
  	    {
  	      _M_set_indeterminate();
--- 421,430 ----
  
  	  // NB: Need this so that external byte sequence reflects
  	  // internal buffer.
! 	  //_M_file->sync();
! 	  // Or do we?  We really want to make sure that the IO layer
! 	  // below us has all the bytes from our buffer, not force
! 	  // them to do something inefficient... -LJR
  	  if (__len == __plen)
  	    {
  	      _M_set_indeterminate();

Test case (I can only see putting this in dejagnu if we had an
automatic, portable way to assess system call statistics and patterns, etc):

#include <iostream>

int main ()
{
  for (int i = 0; i < 25; i++)
    std::cout << "Test line of output - to make a system call or delay?"
      << " That is the question." << std::endl;
}

Results with patch:

truss a.out             # 25 write system calls since line-buffered
truss >/dev/null a.out  #  2 write calls, one write call per C IO buffer

Results without patch:

truss a.out             # 1900 write system calls!
truss >/dev/null a.out  # 1900 write system calls!

Regards,
Loren


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]