<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Oct 19, 2016, at 11:14 AM, Bruce Hoult via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" class="">llvm-dev@lists.llvm.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote">On Wed, Oct 19, 2016 at 6:24 PM, Benjamin Kramer via llvm-dev <span dir="ltr" class=""><<a href="mailto:llvm-dev@lists.llvm.org" target="_blank" class="">llvm-dev@lists.llvm.org</a>></span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">In terms of performance shared_ptr has a number of disadvantages. One<br class="">
is that it always uses atomics even though most IntrusiveRefCntPtrs<br class="">
are used in single-threaded contexts. Another is weak_ptr adding a lot<br class="">
of complexity to the implementation, IntrusiveRefCntPtr doesn't<br class="">
support weak references.<br class="">
<br class="">
With that it's hard to make a case for changing uses of<br class="">
IntrusiveRefCntPtr as it's a non-trivial amount of work<br class="">
(IntrusiveRefCntPtr binds the reference count to the object itself,<br class="">
shared_ptr doesn't. Figuring out when a value held by an<br class="">
IntrusiveRefCntPtr is passed around by raw pointer and stuffed into<br class="">
another IntrusiveRefCntPtr is hard) with potential negative<br class="">
performance impact.<br class="">
<div class="gmail-HOEnZb"><div class="gmail-h5"><span style="color:rgb(34,34,34)" class=""></span></div></div></blockquote><div class=""> </div><div class="">In terms of performance, the whole concept has a number of disavantages :-)</div><div class=""><br class=""></div><div class="">I recently tried an experiment. I compiled a 40000 line C file (concatenated all the files of a project together) to .bc with clang, and then ran llc on it. I tried it on both Ubuntu 16.04 x64 and on an Odroid XU-4 ARM board. with very similar results.</div><div class=""><br class=""></div><div class="">I made a tiny library with a 1 GB static char array. I made a malloc() that simply bumped a pointer (prepending a 32 bit object size, just for realloc(), grrrrrr kill it with fire), and a free() that is an empty function. There's a calloc() that calls the above malloc() and then memset(). And a realloc() that is a no-op if the size is smaller, or does malloc(), memcpy() if bigger.</div><div class=""><br class=""></div><div class="">Then I used LD_PRELOAD to replace the standard malloc library with mine.</div><div class=""><br class=""></div><div class="">Result: ~10% faster execution than llc without LD_PRELOAD, and ~180 MB of the array used (120 MB on the 32 bit ARM).</div><div class=""><br class=""></div><div class="">Then I built BDW GC as a malloc replacement (with free() as a no-op) and used LD_PRELOAD with it.</div><div class=""><br class=""></div><div class="">Result: ~20% faster execution than llc without LD_PRELOAD, and ~10 MB of RAM used.</div><div class=""><br class=""></div><div class="">In this experiment all the reference counting in IntrusiveRefCntPtr or shared_ptr or whatever still takes place, the same as before. But at the end, when it decides to call free, it's a no-op. So all the reference-counting machinery is a complete waste of time and code and RAM and the program would run strictly faster if it was ripped out.</div></div></div></div></div></blockquote><div><br class=""></div><div>I may miss something in your description, but it seems like you’re never releasing memory? I’m not sure I follow how is it a good thing? </div><div>Also what about destructor?</div><div><br class=""></div><div>— </div><div>Mehdi</div><div><br class=""></div><div><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""><br class=""></div><div class="">I don't know for sure (it's a lot more work to try!), but I would not be surprised to see a further 10%-20% speedup.</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">And then you come to the cognitive load on the programmer, trying to decide whether to use IntrusiveRefCntPtr or shared_ptr or unique_ptr or auto_ptr or weak_ptr or whether and where to call free()/delete. And the extra typing needed to write it instead of using a raw pointer. And the extra time and cognitive load to read the code. And for what? </div><div class=""><br class=""></div></div></div></div>
_______________________________________________<br class="">LLVM Developers mailing list<br class=""><a href="mailto:llvm-dev@lists.llvm.org" class="">llvm-dev@lists.llvm.org</a><br class="">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev<br class=""></div></blockquote></div><br class=""></body></html>