simon-git: spigot (master): Simon Tatham

Commits to Tartarus hosted VCS tartarus-commits at lists.tartarus.org
Thu Aug 15 23:23:43 BST 2019


TL;DR:
  6ca2926 Refactor dgreet() to automate class-name printing.
  78d972d Permit --debug to take a class name as an argument.
  7d04900 Replace pi/tau implementation with Chudnovsky's formula.

Repository:     https://git.tartarus.org/simon/spigot.git
On the web:     https://git.tartarus.org/?p=simon/spigot.git
Branch updated: master
Committer:      Simon Tatham <anakin at pobox.com>
Date:           2019-08-15 23:23:43

commit 6ca292639edcb4042e1904f600d995706b01fd22
web diff https://git.tartarus.org/?p=simon/spigot.git;a=commitdiff;h=6ca292639edcb4042e1904f600d995706b01fd22;hp=34f87c27cd20e509e7ba0f145d933c443faaf1d3
Author: Simon Tatham <anakin at pobox.com>
Date:   Thu Aug 15 23:15:05 2019 +0100

    Refactor dgreet() to automate class-name printing.
    
    Now debuggable objects' initial calls to dgreet() don't have to start
    with the boilerplate "hello" and the classname. That's generated
    automatically, so all you have to write is
    
        dgreet();    // if no further information (conveniently) available
        dgreet("foo=", foo, " bar=", bar);  // if params can usefully be printed
    
    where previously you'd have had to write those as
    
        dgreet("hello SomeClassName");
        dgreet("hello SomeOtherClassName foo=", foo, " bar=", bar);
    
    The mechanism for this is that there's a macro MAKE_CLASS_GREETER,
    which defines a function that takes a pointer to a given class as a
    parameter, ignores it, and (via cpp stringification) returns an object
    containing a string representation of the same class name. So you
    write MAKE_CLASS_GREETER(SomeClassName) at file scope somewhere it'll
    be available to the class's constructor, and then the expansion of the
    dgreet() macro includes a function call passing 'this' to that
    function, which will select the right overload of the macro-generated
    function even if more than one is present in a given translation unit.
    
    Hence, the class names in debug greetings are generated automatically,
    which means no typos and less boilerplate. (And if you try to use
    dgreet() in the absence of one of those class-name retrieval
    functions, you'll get a compile error to remind you.)
    
    Partly the aim of this is to reduce the amount of boring typing I have
    to do. But mostly, it's to make the names of debuggable class types
    available to spigot at run time, which I'm about to use for extra
    --debug functionality.
    
    Notes on the diff for this commit: _most_ of the changes are a
    completely boring and mechanical translation of every dgreet() call
    into the new format, and adding MAKE_CLASS_GREETER invocations all
    over the place. The interesting parts are in spigot.h, where I add a
    mechanism for Debuggable to store a class name, implement the
    MAKE_CLASS_GREETER macro, and rewrite the dprint() and dgreet() macros
    and their system of variadically templated underlying inline
    functions.

 algebraic.cpp  |  9 ++++++---
 arithmetic.cpp |  6 ++++--
 baseout.cpp    |  4 +++-
 cfracout.cpp   |  4 +++-
 consts.cpp     | 24 ++++++++++++++++++------
 enforce.cpp    |  4 +++-
 erf.cpp        |  4 +++-
 exp.cpp        | 13 +++++++++----
 expint.cpp     | 20 +++++++++++++++-----
 gamma.cpp      | 16 ++++++++++++----
 holefiller.cpp |  4 +++-
 hypergeom.cpp  | 21 +++++++++++++++------
 io.cpp         |  9 ++++++---
 monotone.cpp   |  8 ++++++--
 spigot.cpp     | 34 ++++++++++++++++++++++++++-------
 spigot.h       | 59 ++++++++++++++++++++++++++++++++++++++++++++--------------
 sqrt.cpp       | 12 +++++++++---
 trig.cpp       | 16 ++++++++++++----
 trigint.cpp    |  5 +++--
 unary.cpp      |  8 ++++++--
 zeta.cpp       |  4 +++-
 21 files changed, 211 insertions(+), 73 deletions(-)

commit 78d972dd53caebf904d5c99c1f6b70167b219301
web diff https://git.tartarus.org/?p=simon/spigot.git;a=commitdiff;h=78d972dd53caebf904d5c99c1f6b70167b219301;hp=6ca292639edcb4042e1904f600d995706b01fd22
Author: Simon Tatham <anakin at pobox.com>
Date:   Thu Aug 15 23:15:05 2019 +0100

    Permit --debug to take a class name as an argument.
    
    Now if I know which class I want to examine the progress of, I can
    write things like 'spigot --debug=AlgebraicPrep', or 'spigot
    --debug=Core2', which is easier than the previous approach of starting
    with '--debug=greetings', grepping out the numeric debug id of the
    class instance I was interested in, and then re-running with that id.
    
    This is achieved by adapting the previous commit so that the
    MAKE_CLASS_GREETER function returns a special Debuggable::ClassName
    object in place of a string. All those objects are declared at file
    scope to ensure they're constructed at startup, and the constructor
    automatically registers each object in a centralised list, similarly
    to the registration system in expr.cpp introduced by commit 3c9df5aa7.
    So the option-parsing code in main() knows what's a legal class name
    and what isn't, and it can even print a list of all of them if you
    need it to (via the option --debug=help).
    
    At the moment, the new --debug=ClassName syntax will print all debug
    messages from all instances of that class. So if there are lots (e.g.
    it's a class used by the operand to MonotoneHelper), they may all be
    interleaved. I'm undecided about whether that's the best thing; I may
    yet introduce further refinements like --debug=ClassName:greetings
    (equivalent to --debug=greetings | grep ClassName), or
    --debug=ClassName:first, or --debug=ClassName:12 (for the 12th
    instance)...

 main.cpp   | 28 +++++++++++++++++++++++++++-
 spigot.cpp | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++--
 spigot.h   | 24 ++++++++++++++++++++++--
 3 files changed, 100 insertions(+), 5 deletions(-)

commit 7d049000e69c16f0fcff91ecf2c4af8de39c0569
web diff https://git.tartarus.org/?p=simon/spigot.git;a=commitdiff;h=7d049000e69c16f0fcff91ecf2c4af8de39c0569;hp=78d972dd53caebf904d5c99c1f6b70167b219301
Author: Simon Tatham <anakin at pobox.com>
Date:   Thu Aug 15 23:15:06 2019 +0100

    Replace pi/tau implementation with Chudnovsky's formula.
    
    I found out about this quite recently. It consists of a very silly-
    looking infinite series, which converges linearly but with a very good
    constant of proportionality: the terms decrease by a factor of about
    1.5e14 each time, i.e. you get 14 extra decimal digits of precision
    per term!
    
    The downside is that once you've summed the series, you have to take
    the reciprocal and multiply by sqrt(10005) to get to a rational
    multiple of pi. But the fast convergence more than makes up for that:
    in a speed test over 100,000 digits, I found this implementation wins
    by nearly a factor of two over spigot's previous strategy of using
    Machin's formula. So it's definitely worth switching.
    
    The series is actually expressible as an instance of the generalised
    hypergeometric function. You can implement this pi-evaluation strategy
    manually in spigot's existing expression language by writing
    
      let chudnovsky_pi = 426880/13591409 sqrt(10005) /
          Hg(1/6, 1/2, 5/6, 558731543/545140134;
             1, 1, 13591409/545140134;
            -1/53360^3)
    
    and even that is pretty fast. But for the official implementation of
    the built-in constant 'pi', I've handwritten a custom spigot class for
    the series component, which can get away with being more streamlined
    than the existing generalised-hypergeometric machinery, and squeezes
    out a bit of extra speed.
    
    It's natural to wonder if this might also be faster at computing the
    internal constant pi^2/6, because if you square the Chudnovsky formula
    for pi, the sqrt(10005) factor becomes rational, so you end up with a
    pure rational multiple of 1/(sum of series)^2. But I tried it, and the
    existing pi^2/6 implementation is still quite a lot faster, so I've
    left that one as it is. I imagine the Core2 / spigot_square()
    mechanism is probably losing everything that the fast implementation
    of pi gains.

 consts.cpp | 146 +++++++++++++++++++++++++++++++++++++++++++++++--------------
 manual.but |   4 +-
 2 files changed, 114 insertions(+), 36 deletions(-)



More information about the tartarus-commits mailing list