Thread

  1. Re: sinval synchronization considered harmful

    Robert Haas <robertmhaas@gmail.com> — 2011-07-22T03:37:27Z

    On Thu, Jul 21, 2011 at 9:19 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
    > Robert Haas <robertmhaas@gmail.com> writes:
    >> On Thu, Jul 21, 2011 at 6:43 PM, Noah Misch <noah@2ndquadrant.com> wrote:
    >>> On Wed, Jul 20, 2011 at 09:46:33PM -0400, Robert Haas wrote:
    >>>> SIGetDataEntries() can pretty easily be made lock-free.  The only real
    >>>> changes that seem to be are needed are (1) to use a 64-bit counter, so
    >>>> you never need to decrement
    >
    >>> On second thought, won't this be inadequate on 32-bit systems, where updating
    >>> the 64-bit counter produces two stores?  You must avoid reading it between those stores.
    >
    >> Now that is a potentially big problem.
    >
    > Could we do something similar to the xxid hacks?  That is, we have a lot
    > of counters that should be fairly close to each other, so we store only
    > the low-order 32 bits of each notional value, and separately maintain a
    > common high-order word.  You probably would need some additional
    > overhead each time the high-order word bumps, but that's reasonably
    > infrequent.
    
    Well, the trouble is figuring out what the shape of that additional
    overhead needs to look like.  I think I have a simpler idea, though:
    before acquiring any locks, just have SIGetDataEntries() do this:
    
    +       if (stateP->nextMsgNum == segP->maxMsgNum && !stateP->resetState)
    +               return 0;
    
    Patch (with comment explaining why I think this is OK) attached.  If
    the message numbers happen to be equal only because the counter has
    wrapped, then stateP->resetState will be true, so we'll still realize
    we need to do some work.
    
    Test results, with the lazy vxid patch plus this patch, at 8 clients:
    
    tps = 34028.144439 (including connections establishing)
    tps = 34079.085935 (including connections establishing)
    tps = 34125.295938 (including connections establishing)
    
    And at 32 clients:
    
    tps = 185521.605364 (including connections establishing)
    tps = 188250.700451 (including connections establishing)
    tps = 186077.847215 (including connections establishing)
    
    And at 80 clients:
    
    tps = 188568.886569 (including connections establishing)
    tps = 191035.971512 (including connections establishing)
    tps = 189363.019377 (including connections establishing)
    
    Not quite as good as the unlocked version, but better than the
    per-backend mutex, and a whole lot simpler.
    
    -- 
    Robert Haas
    EnterpriseDB: http://www.enterprisedb.com
    The Enterprise PostgreSQL Company