Re: Lock-free reference counting



Stephen Howe <sjhoweATdialDOTpipexDOTcom> wrote:
On Mon, 01 Dec 2008 17:33:50 +0000, Jon Harrop <jon@xxxxxxxxxxxxxxxxx>
wrote:
Stephen Howe <sjhoweATdialDOTpipexDOTcom> wrote:
You said, "Which are scattered across memory.". I am pointing out that
the counters are _NOT_ scattered in memory...

That is incorrect.

if the reference counters are instrusive, the reference counters are
adjacent in memory to the object they count.

The objects themselves are scattered across memory => the references in
them are also scattered.

No. Effectively when memory was allocated for object it was
sizeof(object)+sizeof(counter). The counter is _ADJACENT_ to the
object. Granted if you had 4000 objects they may be scattered
thoughout memory, but in every case, their counters are adjacent.

The counters are in with the object and the objects are scattered across
memory, yes.

You are describing extrusive pointers (where the counter maybe
somewhere else in memory from the object)...

No, that is not what I am describing.

Reference counts only exist to get bumped and they are bumped under a
variety of different circumstances including many where the data in the
object itself is not touched.

Even swapping a pair of reference counted smart pointers in an array over
incurs several memory accesses to locations that would otherwise have been
untouched.

Not necessarily so with C++. swap may be specialised for the reference
countered pointers. I make that 2 reads, 2 writes for that swap
(assuming that a pointer & counter can be moved to a register) which
any decent compiler will do.

A triumph of hope over reality. Here is an example program that runs 2x
slower than necessary when compiled with GCC 4.3.2 on x86:

#include <iostream>
#include <vector>
#include <algorithm>
#include <boost/shared_ptr.hpp>

using namespace std;
using namespace boost;

int cmp(shared_ptr<int> a, shared_ptr<int> b)
{
return *a < *b;
}

int main(int argc, char *argv[])
{
vector<shared_ptr<int> > a;
const int n = (argc > 1 ? atoi(argv[1]) : 1000000);
cout << n << endl;
for (int i=0; i<n; ++i)
{
shared_ptr<int> k(new int);
*k = n - i;
a.push_back(k);
}
sort(a.begin(), a.end(), cmp);
return 0;
}

Profiling shows that 60% of the time is spent bumping counters precisely
because GCC fails to make that optimization.

An example: swap is specialised for std::vector which allows 2 vectors
to be swapped without swapping container contents at all (providing
the allocators are the same). It amounts to swapping 3 pointers.
The same is true for std::deque and other containers. More to the
point, the objects that the vectors are managing are untouched after
the swap.

Same is true std::string. You can swap strings, not a single character
is copied or moved. Nothing is allocated or deallocated.

And I stress again that your array example of bumping is only true if
the array is an array of smart pointers. If those are references or
pointers the bumpoing does not occur (mind you there is now an extra
level of indirection, you have not gained much).

I agree that such optimizations exist and can even be done by hand but then
you've lost the only advantage reference counting ever had: simplicity.

--
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/?u
.



Relevant Pages

  • Re: Lock-free reference counting
    ... the counters are _NOT_ scattered in memory... ... adjacent in memory to the object they count. ... reference counts are _NEVER_ bumped. ... explicitly mutate counters is right before I hand a pointer to an object ...
    (comp.programming)
  • Re: Lock-free reference counting
    ... do with initializing it. ... Which are scattered across memory. ... That depends on whether the counters are intrusive or extrusive. ... incorrect because reference counts get bumped even when the value itself is ...
    (comp.programming)
  • Re: Large Memory Footprint for Simple .NET Apps
    ... Memory counters have a name,f.i.Taskmanager shows 'Mem Usage' and 'VM Size' ... The Performance monitor has a whole bunch of named Memory ... > the Task Manager. ...
    (microsoft.public.dotnet.general)
  • Re: Allocated memory alerts and changed threshold still doesnt si
    ... When I add the other counters I get a ... I understand that you receive performance alert emails ... know, SBS is a higher integrated Server including Exchange, SQL and ISA. ... have to check which process used high CPU and Memory utilization. ...
    (microsoft.public.windows.server.sbs)
  • Re: Lock-free reference counting
    ... Which are scattered across memory. ... That depends on whether the counters are intrusive or extrusive. ... incorrect because reference counts get bumped even when the value itself is ... Your statemet is likely to be true for extrusive counters. ...
    (comp.programming)