home bbs files messages ]

Forums before death by AOL, social media and spammers... "We can't have nice things"

   comp.lang.c++.moderated      Moderated discussion of C++ superhackery      33,346 messages   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]

   Message 31,560 of 33,346   
   Marc to Pete Becker   
   Re: atomic counter   
   12 Oct 11 13:58:06   
   
   From: marc.glisse@gmail.com   
      
   Pete Becker  wrote:   
      
   > On 2011-10-09 12:27:42 +0000, Marc said:   
   >   
   >> I am trying to make our reference counting implementation thread-safe   
   >> (for a very basic definition of thread-safe), which essentially means   
   >> making the counter atomic. However, there are many options to atomic   
   >> operations, in particular concerning the memory model, and I want to   
   >> make sure I get it right.   
   >>   
   >> The operations I use are increment (no return), decrement (and check   
   >> if the return value is 0), store (to initialize) and load (to check if   
   >> the object is not shared and thus safe to write into).   
   >>   
   >> It looks to me like memory_order_relaxed should be good enough for   
   >> this purpose, as I don't see what synchronization would be needed with   
   >> the rest of memory, but I may be missing something fundamental there.   
   >   
   > Suppose there are two references to the object, in two different   
   > threads. One thread decrements the reference count, then the other   
   > does. If the decrement from the first thread isn't seen by the second   
   > thread, the second thread won't see that the count has become zero, and   
   > the object won't get destroyed. So memory_order_relaxed won't work: you   
   > need to ensure that the result of a decrement is visible to another   
   > thread that also needs to decrement the count.   
      
   Uh? I am still calling an atomic decrement function. The standard says:   
      
   "Note: Atomic operations specifying memory_order_relaxed are relaxed   
   with respect to memory ordering.  Implementations must still guarantee   
   that any given atomic access to a particular atomic object be   
   indivisible with respect to all other atomic accesses to that object."   
      
   I thought the memory order was mostly concerned with what happened to   
   the rest of the memory.   
      
   Assuming your interpretation is correct, what is memory_order_relaxed   
   good for?   
      
   > It's easier to get the code right when it's sequentially consistent. In   
   > general, unless you can demonstrate that synchronization is a   
   > bottleneck, don't mess with it.   
      
   Well yes, of course, I did some experiments (using boost::shared_ptr   
   or the libstdc++ std::atomic (just a place-holder implementation, I   
   know)), and the slow-down was unacceptable, which led me to   
   reimplement it, and the performance hit is acceptable but still   
   noticable enough that I am not sure about enabling it by default for   
   MT programs (some programs have several threads that don't share any   
   ref-counted objects and would pay the price for nothing).   
      
   Our main target is x86/x86_64 where as far as I understand (please   
   correct me if I am wrong) the memory barrier is unavoidable (implied   
   by any atomic operation), but I am still interested in not penalizing   
   our users on other platforms if I don't have to.   
      
   And it is intellectually satisfying to understand things ;-)   
      
   Thank you for your answer.   
      
      
   --   
         [ See http://www.gotw.ca/resources/clcm.htm for info about ]   
         [ comp.lang.c++.moderated.    First time posters: Do this! ]   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]


(c) 1994,  bbs@darkrealms.ca