tag:blogger.com,1999:blog-5246987755651065286.post1890920695473194237..comments2024-02-22T16:15:42.388-08:00Comments on cbloom rants: 07-14-11 - compare_exchange_strong vs compare_exchange_weakcbloomhttp://www.blogger.com/profile/10714564834899413045noreply@blogger.comBlogger5125tag:blogger.com,1999:blog-5246987755651065286.post-77425338744195901692011-07-26T14:06:09.500-07:002011-07-26T14:06:09.500-07:00Ah, thanks for the clarification.
I think non-con...Ah, thanks for the clarification.<br /><br />I think non-const references are pretty much always horrible.<br /><br />I literally thought there was a bug in my code the first time I ported some Win32 code from InterlockedCompareExchnage to C++0x compare_exchange because it kept changing my value of "old".<br /><br />In fact back when I got to use C++ and pick my own coding style, I very much liked the convention that all const objects are passed by ref and all non-const are passed by pointer; this makes it super clear at the call site which args can be mutated and which can't. I miss that code base a lot. Oh well...cbloomhttps://www.blogger.com/profile/10714564834899413045noreply@blogger.comtag:blogger.com,1999:blog-5246987755651065286.post-71160711692096000232011-07-26T13:50:54.229-07:002011-07-26T13:50:54.229-07:00The non-member compare_exchange_weak and compare_e...The non-member compare_exchange_weak and compare_exchange_strong functions take their arguments by pointer, for C compatibility. It is the member functions which take references. e.g.<br /><br />std::atomic<int> ai;<br /><br />int old=0;<br /><br />if(ai.compare_exchange_strong(old,1))<br /> do_something();<br /><br />or alternatively<br /><br />if(compare_exchange_strong(&ai,&old,1))<br /> do_something();Anthony Williamshttps://www.blogger.com/profile/12888842046584695509noreply@blogger.comtag:blogger.com,1999:blog-5246987755651065286.post-35372056584744938212011-07-14T17:31:49.388-07:002011-07-14T17:31:49.388-07:00IMO there could easily be more things in the C sta...IMO there could easily be more things in the C standards that are like :<br /><br />if the platform has a native vector type then the syntax for using it is "vector[4] int x;"<br /><br />and then provide a mechanism like<br /><br />#if platform supports(vector[4] int)<br /> .. simd code ..<br />#else<br /> .. non-simd code ..<br />#endif<br /><br />I dunno, this is an unrelated rant.<br /><br />Like I feel like C has two parts (actually make 3 or 4 parts), like there's the core bit of basic C stuff that every platform has to support. Then there's stuff that platforms may or may not have, for example I should be able to ask things like (#if platform unaligned-load-fast) - rather than just leaving that a big undefined mess.<br /><br />Anyhoo...cbloomhttps://www.blogger.com/profile/10714564834899413045noreply@blogger.comtag:blogger.com,1999:blog-5246987755651065286.post-33485957890736663112011-07-14T17:28:02.986-07:002011-07-14T17:28:02.986-07:00All of the platforms with LL/SC provide intrinsics...All of the platforms with LL/SC provide intrinsics for LL/SC , so you have that problem anyway. It's just at the moment I have to do rigamorale like<br /><br />#if PPC<br />__lwarx()<br />#elif ARMV6<br />__ldrex()<br />#else<br />...<br /><br />granted, you're right that it is ugly in C and can produce subtly broken code, but we have that problem anyway.<br /><br />This is the classic cop-out of C standardization if it's messy or varies by platform they leave it undefined. But that doesn't make the problem go away. It just makes it *worse* because now it's left up to each compiler implementation on each platform, so now you have not only a messy problem, but one that's different everywhere and badly documented, and etc..cbloomhttps://www.blogger.com/profile/10714564834899413045noreply@blogger.comtag:blogger.com,1999:blog-5246987755651065286.post-43989812969434349542011-07-14T14:07:11.802-07:002011-07-14T14:07:11.802-07:00I'd rather see things in the standard like &qu...<i>I'd rather see things in the standard like "if LL-SC exist on this architecture, then they can be invoked via __ll() and __sc()"</i><br />The problem with LL/SC is that they often come with limitations that are near-impossible to express in C/C++; e.g. on some implementations, you're not allowed to have any other memory access between a LL/SC pair (doing so will cause you to lose the reservation). In ASM that's no problem, just don't do loads/stores, but how do you express it in C/C++ where there's no binding way to force a value into a register, and even seemingly innocent things like adding a literal constant might require an extra memory access to load the constant from memory?<br /><br />The truth is that on the micro level, most compilers aren't aware of such limitations, even if the underlying architecture or implementation has them. You just shove it all into intrinsics that are expanded very late into the compilation process, after any optimizations that might screw them up.ryghttps://www.blogger.com/profile/03031635656201499907noreply@blogger.com