{"id":3903,"date":"2014-11-13T10:35:57","date_gmt":"2014-11-13T00:35:57","guid":{"rendered":"https:\/\/www.flamingspork.com\/blog\/?p=3903"},"modified":"2014-11-13T10:35:57","modified_gmt":"2014-11-13T00:35:57","slug":"volatile-considered-harmful","status":"publish","type":"post","link":"https:\/\/www.flamingspork.com\/blog\/2014\/11\/13\/volatile-considered-harmful\/","title":{"rendered":"volatile considered harmful"},"content":{"rendered":"<p>While playing with MySQL 5.7.5 on POWER8, I came across a rather interesting bug (<a href=\"http:\/\/bugs.mysql.com\/bug.php?id=74775\">74775 <\/a>&#8211; and this is not the only one&#8230; I think I have a decent amount of auditing and patching to do now) which made me want to write a bit on memory barriers and the volatile keyword.<\/p>\n<p>Memory barriers are hard.<\/p>\n<p>Like, super hard. It&#8217;s the kind of thing that makes you curse hardware designers, probably because they&#8217;re not magically solving all your problems for you. Basically, as you get more CPU cores and each of them have caches, it gets more expensive to keep everything in sync. It&#8217;s quite obvious that with *ahem* an eventually consistent model, you could save a bunch of time and effort at the expense of shifting some complexity into software.<\/p>\n<p>Those in the MySQL world should recognize this &#8211; we&#8217;ve been dealing with asynchronous replication for well over a decade as a good way to scale.<\/p>\n<p>On some CPU architectures (POWER for example) not all loads are created equal. When you load a value from memory, it will be consistent with your thread of execution. That is, with any stores that <strong>you<\/strong> have done in <strong>this thread of execution.<\/strong> If another thread updates that memory location you <strong>may not see that update<\/strong> even if your load occurs <strong>after<\/strong> that thread updates that memory location. Think <strong>eventually consistent.<\/strong><\/p>\n<p>If you want up to date reads (and not clobber writes), then you get to do memory barriers! (a topic for elsewhere &#8211; the PowerISA document has good explanations of what we have on POWER though, and how load with reserve works).<\/p>\n<p>What the <strong>volatile<\/strong> keyword does is generate load and store instructions. It is useful when talking to hardware, as the load and store instructions are actually doing something there that the compiler doesn&#8217;t know about and thus shouldn&#8217;t optimize away.<\/p>\n<p>The <strong>volatile<\/strong> keyword does <strong>not<\/strong> add any memory barriers. This is <strong>important <\/strong>to realize &#8211; <strong>volatile just makes loads and stores happen for your thread, not in relation to any other threads of execution. <\/strong>Thus, you<strong> cannot<\/strong> use volatile as a thread synchronization mechanism <strong>at all<\/strong>. It is <strong>completely and totally wrong<\/strong>.<\/p>\n<p>Basically, if you have a volatile variable and you do stores to it in one thread and loads in another, after the store happens, it could be <strong>quite a long time<\/strong> before the thread doing the loads sees it! For some applications this may be okay (although I can&#8217;t really think of any beyond very very inaccurate status variables)&#8230; but if it matters <strong>at all<\/strong> for application correctness, volatile is the wrong thing to use.<\/p>\n<p>Further reading:<\/p>\n<ul>\n<li><a href=\"https:\/\/en.wikipedia.org\/wiki\/Memory_barrier\">https:\/\/en.wikipedia.org\/wiki\/Memory_barrier<\/a><\/li>\n<li><a href=\"https:\/\/www.kernel.org\/doc\/Documentation\/volatile-considered-harmful.txt\">https:\/\/www.kernel.org\/doc\/Documentation\/volatile-considered-harmful.txt<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>While playing with MySQL 5.7.5 on POWER8, I came across a rather interesting bug (74775 &#8211; and this is not the only one&#8230; I think I have a decent amount of auditing and patching to do now) which made me &hellip; <a href=\"https:\/\/www.flamingspork.com\/blog\/2014\/11\/13\/volatile-considered-harmful\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[76,570,14],"tags":[613,525,628,562,39,614],"class_list":["post-3903","post","type-post","status-publish","format-standard","hentry","category-code","category-ibm-work-et-al","category-mysql","tag-barrier","tag-memory","tag-mysql","tag-power","tag-programming","tag-volatile"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p5a6n8-10X","jetpack-related-posts":[{"id":4035,"url":"https:\/\/www.flamingspork.com\/blog\/2016\/02\/26\/mysql-contributions-status\/","url_meta":{"origin":3903,"position":0},"title":"MySQL Contributions status","author":"Stewart Smith","date":"2016-02-26","format":false,"excerpt":"This post is an update to the status of various MySQL bugs (some with patches) that I've filed over the past couple of years (or that people around me have). I'm not looking at POWER specific ones, as there are these too, but each of these bugs here deal with\u2026","rel":"","context":"In &quot;code&quot;","block_context":{"text":"code","link":"https:\/\/www.flamingspork.com\/blog\/category\/code\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":3899,"url":"https:\/\/www.flamingspork.com\/blog\/2014\/11\/11\/mysql-cluster-on-power8\/","url_meta":{"origin":3903,"position":1},"title":"MySQL Cluster on POWER8","author":"Stewart Smith","date":"2014-11-11","format":false,"excerpt":"So, I've written previously on MySQL on POWER, and today is a quick bit of news about MySQL Cluster on POWER - specifically MySQL Cluster 7.3.7. I ran into three main issues in getting some flexAsync benchmark results. One of them was the fact that I wanted to do this\u2026","rel":"","context":"In &quot;code&quot;","block_context":{"text":"code","link":"https:\/\/www.flamingspork.com\/blog\/category\/code\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":3752,"url":"https:\/\/www.flamingspork.com\/blog\/2014\/06\/03\/mysql-5-6-on-power-patch-available\/","url_meta":{"origin":3903,"position":2},"title":"MySQL 5.6 on POWER (patch available)","author":"Stewart Smith","date":"2014-06-03","format":false,"excerpt":"The following sentence is brought to you by IBM Legal. The postings on this site are my own and don't necessarily represent IBM's positions, strategies or opinions. Okay, now that is out of the way.... If you're the kind of person who follows the MySQL bugs database closely or subscribes\u2026","rel":"","context":"In &quot;code&quot;","block_context":{"text":"code","link":"https:\/\/www.flamingspork.com\/blog\/category\/code\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":3755,"url":"https:\/\/www.flamingspork.com\/blog\/2014\/06\/03\/mysql-5-6-performance-on-power8\/","url_meta":{"origin":3903,"position":3},"title":"MySQL 5.6 Performance on POWER8","author":"Stewart Smith","date":"2014-06-03","format":false,"excerpt":"The following sentence is brought to you by IBM Legal: The postings on this site are my own and don't necessarily represent IBM's positions, strategies or opinions. My previous post covered the work needed to get MySQL 5.6.17 running reliably on modern POWER systems. The patch to MySQL 5.6.17 that's\u2026","rel":"","context":"In &quot;IBM&quot;","block_context":{"text":"IBM","link":"https:\/\/www.flamingspork.com\/blog\/category\/work-et-al\/ibm-work-et-al\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":3778,"url":"https:\/\/www.flamingspork.com\/blog\/2014\/07\/17\/update-on-mysql-on-power8\/","url_meta":{"origin":3903,"position":4},"title":"Update on MySQL on POWER8","author":"Stewart Smith","date":"2014-07-17","format":false,"excerpt":"About 1.5 months ago I blogged on MySQL 5.6 on POWER andtalked about what I had to poke at to make modern MySQL versions run and run well on shiny POWER8 systems. One of those bugs, MySQL bug 47213 (InnoDB mutex\/rw_lock should be conscious of memory ordering other than Intel)\u2026","rel":"","context":"In &quot;code&quot;","block_context":{"text":"code","link":"https:\/\/www.flamingspork.com\/blog\/category\/code\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":3901,"url":"https:\/\/www.flamingspork.com\/blog\/2014\/11\/12\/preliminary-mysql-cluster-benchmark-results-on-power8\/","url_meta":{"origin":3903,"position":5},"title":"Preliminary MySQL Cluster benchmark results on POWER8","author":"Stewart Smith","date":"2014-11-12","format":false,"excerpt":"Yesterday, I got the basics going for MySQL Cluster on POWER. Today, I finished up a couple more patches to improve performance and ran some benchmarks. This is on a 3.7Ghz POWER8 machine with non-balanced memory (only 2 of the 4 NUMA nodes have memory, so we have less total\u2026","rel":"","context":"In &quot;code&quot;","block_context":{"text":"code","link":"https:\/\/www.flamingspork.com\/blog\/category\/code\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/www.flamingspork.com\/blog\/wp-json\/wp\/v2\/posts\/3903","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.flamingspork.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.flamingspork.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.flamingspork.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.flamingspork.com\/blog\/wp-json\/wp\/v2\/comments?post=3903"}],"version-history":[{"count":1,"href":"https:\/\/www.flamingspork.com\/blog\/wp-json\/wp\/v2\/posts\/3903\/revisions"}],"predecessor-version":[{"id":3904,"href":"https:\/\/www.flamingspork.com\/blog\/wp-json\/wp\/v2\/posts\/3903\/revisions\/3904"}],"wp:attachment":[{"href":"https:\/\/www.flamingspork.com\/blog\/wp-json\/wp\/v2\/media?parent=3903"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.flamingspork.com\/blog\/wp-json\/wp\/v2\/categories?post=3903"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.flamingspork.com\/blog\/wp-json\/wp\/v2\/tags?post=3903"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}