Boost logo

Boost :

Subject: Re: [boost] [Block Pointer] Up to 600% faster than Shared Pointer
From: Phil Bouchard (philippeb8_at_[hidden])
Date: 2016-03-12 13:25:03


On 03/12/2016 05:18 AM, Rob Stewart wrote:
> On March 11, 2016 9:38:46 PM EST, Phil Bouchard <philippeb8_at_[hidden]> wrote:
>> - I made the proxy explicit. Now it can be used 3 different ways:
>>
>> 1) Clothesline style:
>>
>> block_proxy x;
>> block_ptr<int> v(x, new block<int>(11));
>> block_ptr<int> w(x, new block<int>(12));
>>
>>
>> 2) Root style:
>>
>> proxy_ptr<char[9]> u(new block<char[9]>());
>>
>>
>> 3) Container style (very easy to write containers now):
>>
>> struct list : block_proxy {
>> public:
>> list() : root(*this) {}
>> [...]
>> private:
>> block_ptr<node> root;
>> };
>
> I simplified the syntax of the first two examples, but this still seems complicated given the various components and ways to combine and use them. I don't even know the point.

1) and 3) are slightly more complicated but it'll be used by library
writers (to explicitly assign a proxy to a pointer).

- The end user will use simple assignments operations like:
t100.sub_[1].second = new block<neuron_sight>("vodka|water");

- You can write circular containers and neural networks without worrying
about the destructor; you know that everything will be destructed
deterministically.

>> - If we use fastblock<>() then the speedup can go up to 600% compared
>> to shared_ptr<>:
>
> That's yet another piece to the complexity equation.

If people write game engines then I think they will understand this part
easily ;)

>> - Once again all the examples can be found here:
>> https://github.com/philippeb8/block_ptr/tree/master/example
>
> benchmark.cpp seems flawed for numerous reasons. You measure usage of the make function through a function pointer. You don't eliminate cold cache effects on timing each variation. You are timing free store allocations and deallocations, which can have unknown side effects. You aren't accounting for code elision by the optimizer.

I am not accounting for any optimization, specially for block_ptr<>
because I don't even use move semantics yet, etc.

>> - And the pointer itself here:
>> https://github.com/philippeb8/block_ptr/blob/master/include/boost/smart_ptr/block_ptr.hpp
>
> block_proxy provides little or no safety. First, destroying can be changed through the public interface, so why bother with the accessor/mutator pair? Second, init() can be called with any pointer of the required type. Does that type enforce the right semantics? I don't know. (The comment refers to stack pointers by which, again, I think you mean pointers that may belong to an object and can be on the free store as well, so the comment is misleading.)

block_proxy is still in a beta state and it's in a "just works" state.
But eventually it should be protected like "type_info".

> The loop in block_proxy::release() seems odd. First, are you purposely avoiding C++11? Range-based for would be better. You could also use for_each() with a lambda. As it is, why both m and n?

Thanks for pointing this out but like I was saying it's still in a beta
state.

It's possible for me to re-add the unification of sets but I don't think
it's going to be worth it.

> I'd make more comments, but your comments often don't match the functions they adorn and the code is too hard to follow on this small screen. (Long lines and excess whitespace don't help.)

Thanks a lot for your comments, I'd rather know this right now than
after the whole revision process.

Honestly I've been analyzing pretty much all possibilities and I don't
see any other efficient option out there that goes well amongst the C++
standards.

Regards,
-Phil


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk