On Tue, Jul 26, 2011 at 8:11 PM, Robert Haas <robertmhaas@gmail.com> wrote:
>>>> * Can we partition the sinval lock, so we have multiple copies? That
>>>> increases the task for those who trigger an invalidation, but will
>>>> relieve the pressure for most readers.
>>>
>>> Not sure there's a way to meaningfully partition the queue. In any
>>> case, I think the problem being dealt with here is how to update the
>>> read heads of the queue, not its contents.
>>
>> I agree there's no meaningful way to partition the queue, but we can
>> store the information in more than one place to reduce the contention
>> of people requesting it.
>
> I thought about that. Basically, that saves you a factor of N in
> contention on the read side (where N is the number of copies) and
> costs you a factor of N on the write side (you have to update N
> copies, taking a spinlock or lwlock for each). In the limit, you
> could do one copy of the counter per backend.
>
> I think, though, that a lock-free implementation using memory barriers
> is going to end up being the only real solution. We might possibly
> convince ourselves that we're OK with increasing the cost of
> SIInsertDataEntries(), but any solution that involves replication the
> data is still based on doing at least some locking. And I am pretty
> well convinced that even one spinlock acquisition in
> SIInsertDataEntries() is too many.
You might be right, but I think we have little knowledge of how some
memory barrier code you haven't written yet effects performance on
various architectures.
A spinlock per backend would cache very nicely, now you mention it. So
my money would be on the multiple copies.
It's not completely clear to me that updating N copies would be more
expensive. Accessing N low contention copies rather than 1
high-contention value might actually be a win.
--
Simon Riggs http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services