Bug 17140 - Floating point output is slow
Summary: Floating point output is slow
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 3.4.2
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2004-08-23 04:08 UTC by Jerry Quinn
Modified: 2016-01-16 06:00 UTC (History)
5 users (show)

See Also:
Host: i686-pc-linux-gnu
Target:
Build:
Known to work: 2.95
Known to fail: 3.0.4 3.1.2 3.2.3 3.3.5 3.4.2 4.0.0
Last reconfirmed: 2005-12-31 03:19:43


Attachments
floating point patch (12.34 KB, patch)
2004-09-03 12:45 UTC, Jerry Quinn
Details | Diff
jq initial patch, as applied (12.90 KB, patch)
2004-09-03 14:58 UTC, Benjamin Kosnik
Details | Diff
patch round two (12.14 KB, patch)
2004-09-03 15:51 UTC, Benjamin Kosnik
Details | Diff
double printing test (880 bytes, text/plain)
2004-09-04 15:20 UTC, Jerry Quinn
Details
long double test program (1.09 KB, text/plain)
2004-09-04 15:20 UTC, Jerry Quinn
Details
fp test from libio (58.20 KB, application/octet-stream)
2004-09-04 15:27 UTC, Jerry Quinn
Details
patch round 3 (12.80 KB, patch)
2004-09-12 21:33 UTC, Jerry Quinn
Details | Diff
patch as applied (12.71 KB, patch)
2004-11-11 22:52 UTC, Benjamin Kosnik
Details | Diff
patch with fix (13.15 KB, patch)
2004-11-17 04:39 UTC, Jerry Quinn
Details | Diff
Paolo's minor tweaks (__mod, formatting) (12.63 KB, patch)
2004-11-21 23:41 UTC, Paolo Carlini
Details | Diff
Patch with showpoint fix (12.11 KB, patch)
2004-12-16 13:59 UTC, Jerry Quinn
Details | Diff
Rediffed against 1/3/05 mainline (13.09 KB, patch)
2005-01-03 15:23 UTC, Jerry Quinn
Details | Diff
Updated long double test (1.12 KB, text/plain)
2005-01-16 17:11 UTC, Jerry Quinn
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Jerry Quinn 2004-08-23 04:08:38 UTC
This is a place holder for the work I had done on bringing the old gcc 2.95
floating point printing code back into the library.  I had gotten as far as
having working code on x86 for double and long double, but we had stalled on
getting configury bits in place.  I've been busy for a while, but this has still
been in the back of my mind.

Basically, the code is about 3x faster than printf for a subset of numbers where
it can be accurately printed using hardware fp.  When using big ints, it was
about 50% slower than printf on x86 linux.  The code also contains data to print
IBM and VAX fp numbers, but not for c4x fp numbers.

It also had not been tested on platforms other than x86 linux.  However, it
showed promise :-)
Comment 1 Benjamin Kosnik 2004-09-02 18:04:57 UTC
Excellent to see this back in active status.

Jerry, can you attach the current version of your patch here?

Thanks.

Have you tested this on big/small endian machines, and a 64 bit arch?

FYI your approach seems sane to me. I'll review this patch today/tomorrow.

-benjamin
Comment 2 Jerry Quinn 2004-09-03 12:45:03 UTC
Created attachment 7038 [details]
floating point patch
Comment 3 Jerry Quinn 2004-09-03 12:46:26 UTC
So far I've only tested on x86.  I promised Paolo I'd get a test program up, and
I'll try to get it here today.
Comment 4 Benjamin Kosnik 2004-09-03 14:58:42 UTC
Created attachment 7039 [details]
jq initial patch, as applied

 Jerry, here's your patch as applied by me. I had problems with your original
patch.

On this one, I'm getting:

/mnt/hd/src/gcc/libstdc++-v3/src/floatconv.cc: In function `int
std::__dec_exponent(_T, int&, bool&)':
/mnt/hd/src/gcc/libstdc++-v3/src/floatconv.cc:314: error: expected `;' before
numeric constant
/mnt/hd/src/gcc/libstdc++-v3/src/floatconv.cc: In function `char*
std::__dtoa(char*, _T, int, int, int, bool, int*)':
/mnt/hd/src/gcc/libstdc++-v3/src/floatconv.cc:458: error: expected `;' before
"k"
/mnt/hd/src/gcc/libstdc++-v3/src/floatconv.cc:514: error: expected `;' before
numeric constant
/mnt/hd/src/gcc/libstdc++-v3/src/floatconv.cc:531: error: expected
primary-expression before "int"
/mnt/hd/src/gcc/libstdc++-v3/src/floatconv.cc:531: error: `'0'' cannot be used
as a function
/mnt/hd/src/gcc/libstdc++-v3/src/floatconv.cc:531: error: expected `;' before
"L"
/mnt/hd/src/gcc/libstdc++-v3/src/floatconv.cc:533: error: expected `)' before
"eps"
/mnt/hd/src/gcc/libstdc++-v3/src/floatconv.cc:580: error: expected
primary-expression before "int"
/mnt/hd/src/gcc/libstdc++-v3/src/floatconv.cc:580: error: `'0'' cannot be used
as a function
/mnt/hd/src/gcc/libstdc++-v3/src/floatconv.cc:580: error: expected `;' before
"L"
/mnt/hd/src/gcc/libstdc++-v3/src/floatconv.cc:619: error: expected `;' before
numeric constant


with mainline gcc as of 20040901. Are you using 3.4 for this, or did I mangle
the patch? Hmm. 

-benjamin
Comment 5 Benjamin Kosnik 2004-09-03 15:00:08 UTC
Also, if I remember correctly, there was a test program in the last drop of
these sources. I'll try to dig that testsuite entry out of this tarball:

http://people.redhat.com/bkoz/libstdc++-v3.jq.20040127+.tar.bz2
Comment 6 Benjamin Kosnik 2004-09-03 15:51:39 UTC
Created attachment 7040 [details]
patch round two


Whoops, I had made a mistake when hand-applying that patch. Here's the
corrected copy at applies to mainline gcc.

Jerry, I get some new fails with this, on x86/linux. Thoughts?

FAIL: 22_locale/num_put/put/char/1.cc execution test
FAIL: 22_locale/num_put/put/char/wrapped_env.cc execution test
FAIL: 22_locale/num_put/put/char/wrapped_locale.cc execution test
FAIL: 22_locale/num_put/put/wchar_t/1.cc execution test
FAIL: 22_locale/num_put/put/wchar_t/wrapped_env.cc execution test
FAIL: 22_locale/num_put/put/wchar_t/wrapped_locale.cc execution test
FAIL: 27_io/basic_ostream/inserters_arithmetic/char/4402.cc execution test
FAIL: 27_io/basic_ostream/inserters_arithmetic/char/5.cc execution test
FAIL: 27_io/basic_ostream/inserters_arithmetic/char/6.cc execution test

Is anybody else having better luck with this (Paolo?)

-benjamin
Comment 7 Benjamin Kosnik 2004-09-03 15:57:35 UTC
This is a v2 regression. I think the last one, code-wise.
Comment 8 Jerry Quinn 2004-09-04 15:20:06 UTC
Created attachment 7046 [details]
double printing test

Set dorand=true for random numbers, false for integers.  Set dosprintf and
cmpall true to compare the library output to sprintf output.
Comment 9 Jerry Quinn 2004-09-04 15:20:44 UTC
Created attachment 7047 [details]
long double test program

Set dorand=true for random numbers, false for integers.  Set dosprintf and
cmpall true to compare the library output to sprintf output.
Comment 10 Jerry Quinn 2004-09-04 15:21:27 UTC
Weird.  I left a comment before but it didn't go through...

I saw no new testsuite failures when I applied the patch.  But I've been blocked
the last week or so with a failure on compiling libsup++/guard.cc and undeclared
mutex types.  This is on 686-pc-linux-gnu.

I'm attaching versions of my test programs for double and long double.
Comment 11 Jerry Quinn 2004-09-04 15:27:00 UTC
Created attachment 7048 [details]
fp test from libio

I think this is the test I included with the previous incarnation of the patch.

It was drawn from gcc 2.95 libio's testsuite.
Comment 12 Paolo Carlini 2004-09-07 13:51:15 UTC
Thanks Jerry for the tests. 
Comment 13 Jerry Quinn 2004-09-12 21:33:25 UTC
Created attachment 7114 [details]
patch round 3
Comment 14 Benjamin Kosnik 2004-11-11 22:52:11 UTC
Created attachment 7522 [details]
patch as applied


Last patch, as applied to cvs mainline.

I get three fails with this:

FAIL: 26_numerics/complex/complex_inserters_extractors.cc execution test
FAIL: 27_io/basic_ostream/inserters_arithmetic/char/1.cc execution test
FAIL: 27_io/basic_ostream/inserters_arithmetic/wchar_t/1.cc execution test

		=== libstdc++ Summary ===

# of expected passes		3080
# of unexpected failures	3
# of unexpected successes	2
# of expected failures		5
Comment 15 Jerry Quinn 2004-11-15 15:02:20 UTC
I don't see any of those failures.  I updated tonight (11/12).  Did a fresh
config and make (not bootstrap) on x86 pentium M.

FAIL: 23_containers/bitset/input/1.cc (test for excess errors)
FAIL: 23_containers/bitset/to_ulong/1.cc (test for excess errors)
FAIL: 27_io/basic_filebuf/open/char/3.cc (test for excess errors)
FAIL: 27_io/basic_iostream/4.cc (test for excess errors)
FAIL: 27_io/basic_istream/ignore/char/6360.cc (test for excess errors)
FAIL: 27_io/basic_stringstream/str/char/2.cc (test for excess errors)
Comment 16 Benjamin Kosnik 2004-11-15 17:04:05 UTC
Subject: Re:  Floating point output is slow


>I don't see any of those failures.  I updated tonight (11/12).  Did a fresh
>config and make (not bootstrap) on x86 pentium M.

Hmmm. Well, maybe I munged the floatconv.cc file again.

Your patch does not apply, thus my contortions and sadness. If you'd

cvs add src/floatconf.cc

cvsdiff -N src/floatconv.cc

when making patches this would be so much easier....

Failing that, can you attach your version of floatconv.cc to gcc bugzilla, so I can re-test? Thanks.

>FAIL: 23_containers/bitset/input/1.cc (test for excess errors)
>FAIL: 23_containers/bitset/to_ulong/1.cc (test for excess errors)
>FAIL: 27_io/basic_filebuf/open/char/3.cc (test for excess errors)
>FAIL: 27_io/basic_iostream/4.cc (test for excess errors)
>FAIL: 27_io/basic_istream/ignore/char/6360.cc (test for excess errors)
>FAIL: 27_io/basic_stringstream/str/char/2.cc (test for excess errors)

I don't see any of these....
Comment 17 Jerry Quinn 2004-11-15 17:23:41 UTC
OK, my problem is that the patch didn't actually get applied to mainline.  So
it's not so surprising I didn't see the failures.

I'll apply locally and debug.
Comment 18 Jerry Quinn 2004-11-17 04:39:36 UTC
Created attachment 7560 [details]
patch with fix
Comment 19 Jerry Quinn 2004-11-17 04:40:10 UTC
OK - turned out to be a simple bug, not adjusting for the minus sign.  Amazingly
all of the above patches had the bug and I couldn't have had successful tests
with it there.

Here's the updated patch with floatconv.c properly included ;-)  One note is I
used automake-1.9.3 to regen Makefile.in.  If that's an issue, I can hand-edit
the .in file easily enough - just 2 changes.  Fixes the regressions in make check.

If you're OK with the automake stuff I'll check it in, else do the more minimal
edit.
Comment 20 Benjamin Kosnik 2004-11-19 22:25:57 UTC
This patch applies, and passes regression testing on x86/linux. Now I can start
to review it....

Paolo, any chance you can test this as well?

-benjamin
Comment 21 Paolo Carlini 2004-11-19 22:30:57 UTC
Sure, and *sorry* for the delay :-(
I will do that over the weekend, both on ia64 and x86_64.
Comment 22 Paolo Carlini 2004-11-21 23:39:36 UTC
Hi again. As expected, fpfinal3 regtests Ok on x86/x86_64/ia64-linux. I'm 
attaching what I have actually tested: doesn't include the regenerated files and
avoids a warning about the unused __mod argument of _M_insert_float. Tomorrow,
would like to run on the 64-bit machines the specific floating point output tests.

A final note: we should add a testcase for the fixed (corner case) issue with
grouping (which, basically, is a WONTFIX for 3.3 and 3.4)
Comment 23 Paolo Carlini 2004-11-21 23:41:08 UTC
Created attachment 7579 [details]
Paolo's minor tweaks (__mod, formatting)
Comment 24 Paolo Carlini 2004-11-22 09:43:54 UTC
Hi again. I'm now running on the three architectures the following tests:
1-
Comment 25 Paolo Carlini 2004-11-22 09:57:51 UTC
Hi again. I'm now running on the three architectures the following tests
attached to the PR.
 1- fmttest1.cc
 2- fptest.cc
 3- lfptest.cc

The second one seems basically OK, besides some problems, on x86 *only*, of
this type:

fd.x[0]=0x32f8c7de; fd.x[1]=0xbf19c68d;
dtoa   -0.0001
printf -1e-04
mismatch mode e.0
fd.x[0]=0x207c7765; fd.x[1]=0x3fef97c6;
dtoa   1e+00
printf 1e-00

I think we already discussed those a bit with Jerry, seem not serious:
indeed, both x86_64 and ia64 (with a *newer* glibc installed) are 100% OK.

I'm having more problems with fmttest1.cc, which fails on *all* three machines
(assertion at line 4098). Jerry, Benjamin, does it pass for you?

Also, with lfptest.cc, that segfaults consistently on x86_64 and ia64 at
line 56:

  if (dosprintf) sprintf(buf2, "%Lf",fd.d);

Time permitting, I'd like to help investigating the last one, at least.

That's all for now.
Comment 26 Paolo Carlini 2004-11-22 10:37:29 UTC
fmttest1.cc fails like this:
expect[14]: -1.007830e-18
result[14]: -1.00783e-18
Comment 27 Paolo Carlini 2004-11-22 18:13:56 UTC
A bit of additional info for lfptest too: if I set outcpp to true, then,
on x86_64:
nan
Segmentation fault

On ia64:
0.000000
Segmentation fault

right at the first iteration.
Comment 28 Jerry Quinn 2004-12-16 04:43:05 UTC
I finally got some free time again.  The fmttest1 failure is due to showpoint
handling.  Specifically, there's the following hunk in float_to_char_scientific:

      // Insert digits after decimal point
      for (;__prec && *__bp; __prec--)
	*__sbuf++ = __digits[*__bp++ - '0'];
      if (__pad)
	while (__prec--)
	  *__sbuf++ = __digits[0];

That if test should be if (__pad || __showpoint).  I'm still having some trouble
building.  When I get that sorted out, I'll update the patch with this change.

I don't know what's broken w/ 64 bit, though, and still don't really have 64 bit
access.
Comment 29 Jerry Quinn 2004-12-16 13:59:19 UTC
Created attachment 7755 [details]
Patch with showpoint fix

This applies the fix for fmttest1, which now works correctly.
Comment 30 Jerry Quinn 2004-12-20 21:01:19 UTC
Trying on a power4 aix 5.2 box, in the testsuite,
27_io/basic_ostream/inserts_arithmetic/char/1.cc fails, because of a segfault in
frexp(long double, int).  In gdb, the args look fine.  The int seems to be a
valid pointer, since I can set the value without problem.
Comment 31 Jerry Quinn 2004-12-21 19:19:29 UTC
The power4 segfault occurs in frexpl() in libc, which is a result of calling
__builtin_frexpl() inside std::frexp(long double).  I was wondering if it might
be a problem in long double representation.  I think ppc uses 64 bit long
double, which made me think that it should be calling frexp under the covers
rather than frexpl.

I also created a simple test program for frexp that sems to work for double and
not for long double.

This is making me think the problem isn't in this patch.
Comment 32 Jerry Quinn 2004-12-21 19:40:18 UTC
The AIX problem is PR19115.  Paolo, could you see if the same issue happens on
ia64 and x86-64?
Comment 33 Andrew Pinski 2004-12-21 19:42:58 UTC
(In reply to comment #31)
> The power4 segfault occurs in frexpl() in libc, which is a result of calling
> __builtin_frexpl() inside std::frexp(long double).  I was wondering if it might
> be a problem in long double representation.  I think ppc uses 64 bit long
> double, which made me think that it should be calling frexp under the covers
> rather than frexpl.

PPC AIX uses 128bit long doubles.  There are a couple of different issues for 128bit long double 
support in gcc for PPC, see PR 19019 for one of them, in fact that might be the problem here but I don't 
know.
Comment 34 Andrew Pinski 2004-12-21 19:45:15 UTC
Also I should note use of long double functions on tagets where it does not does it will cause a link 
error so be care full with that.
Comment 35 Paolo Carlini 2004-12-21 20:39:46 UTC
Hi everyone, and sorry about the delay of the planned testing on 64-bit arches.
Hopefully, I can do that before Christmas...
Comment 36 Paolo Carlini 2005-01-03 14:58:06 UTC
Hi Jerry, I'm finally ready to work again on x86_64 and ia64 but unfortunately
your latest patch doesn't apply cleanly here:

patching file include/bits/locale_facets.tcc
Hunk #2 FAILED at 1382.

Can you please rediff? Thanks!
Comment 37 Jerry Quinn 2005-01-03 15:23:28 UTC
Created attachment 7864 [details]
Rediffed against 1/3/05 mainline
Comment 38 Paolo Carlini 2005-01-03 15:27:48 UTC
Thanks!
Comment 39 Paolo Carlini 2005-01-03 16:41:21 UTC
Hi again. Some good news: first, I can confirm that fmttest1.cc does not fail
anymore. Morevoer, on x86-64 lfptest fails with gcc3.3 too, therefore something
seems wrong in the testcase, not in fpfinal5.patch. While a I dig a little
deeper on these issues (and do complete tests on ia64 too), maybe Jerry, you
can try to fix lfptest: it would be nice to actually run it to success on the
64-bit machines too... The backtrace is as follows:
(gdb) backtrace
#0  0x0000002a95b2f10b in __printf_fp () from /lib64/tls/libc.so.6
#1  0x0000002a95b2b416 in vfprintf () from /lib64/tls/libc.so.6
#2  0x0000002a95b46659 in vsprintf () from /lib64/tls/libc.so.6
#3  0x0000002a95b31af8 in sprintf () from /lib64/tls/libc.so.6
#4  0x0000000000401114 in main () at lfptest.cc:58

And, if I print fd.d inside gdb just before the segfault:
(gdb) p fd.d
$1 = <invalid float value>

Are we passing to sprintf a completely crazy third arg?!?
Comment 40 Jerry Quinn 2005-01-03 22:05:27 UTC
(In reply to comment #39)
> seems wrong in the testcase, not in fpfinal5.patch. While a I dig a little
> deeper on these issues (and do complete tests on ia64 too), maybe Jerry, you
> can try to fix lfptest: it would be nice to actually run it to success on the
> 64-bit machines too... The backtrace is as follows:
> And, if I print fd.d inside gdb just before the segfault:
> (gdb) p fd.d
> $1 = <invalid float value>

Hmm, I remember that I had to fiddle with the long double values to make them
work on x86.  Not all random bitstrings are valid x86 long doubles.  This test
isn't the most portable, since I generate values by creating random longs and
stitching them together.

I'll have to look up the format for ia64 long double, but we may end up going
back and forth a couple of times to get it right.

Comment 41 Jerry Quinn 2005-01-16 17:09:53 UTC
Subject: Re:  Floating point output is slow

pcarlini at suse dot de wrote:
> ------- Additional Comments From pcarlini at suse dot de  2005-01-03 16:41 -------
> Hi again. Some good news: first, I can confirm that fmttest1.cc does not fail
> anymore. Morevoer, on x86-64 lfptest fails with gcc3.3 too, therefore something
> seems wrong in the testcase, not in fpfinal5.patch. While a I dig a little
> deeper on these issues (and do complete tests on ia64 too), maybe Jerry, you
> can try to fix lfptest: it would be nice to actually run it to success on the
> 64-bit machines too... The backtrace is as follows:
> (gdb) backtrace
> #0  0x0000002a95b2f10b in __printf_fp () from /lib64/tls/libc.so.6
> #1  0x0000002a95b2b416 in vfprintf () from /lib64/tls/libc.so.6
> #2  0x0000002a95b46659 in vsprintf () from /lib64/tls/libc.so.6
> #3  0x0000002a95b31af8 in sprintf () from /lib64/tls/libc.so.6
> #4  0x0000000000401114 in main () at lfptest.cc:58
> 
> And, if I print fd.d inside gdb just before the segfault:
> (gdb) p fd.d
> $1 = <invalid float value>
> 
> Are we passing to sprintf a completely crazy third arg?!?

Sorry about the delay.  I'm really not sure what's wrong with the test 
program.  The backtrace only says that it doesn't like the random long double 
I'm generating.

It appears that x86-64 uses the same long double as x86.  The only thing I can 
think of is that the libs get upset if the top 32 bits that are unused have 
junk in them.  I'm attaching a copy of lfptest that zeros out the top 32 bits 
so that there are only 80 bits of random numbers and the rest of 128 bits are 
zero.

The other thing you can try is to run the test with dorand=false.  This makes 
it use the loop index as the number to print.  It's also a good test to run 
and can flush out different problems than the random test.

Comment 42 Jerry Quinn 2005-01-16 17:11:45 UTC
Created attachment 7967 [details]
Updated long double test

Zero's out 4th word in long double on 80 bit values
Comment 43 Paolo Carlini 2005-01-16 17:13:47 UTC
Ok, will follow your suggestions.
Comment 44 Andrew Pinski 2005-01-26 14:34:27 UTC
*** Bug 19642 has been marked as a duplicate of this bug. ***