{"id":4848,"date":"2016-08-09T05:54:53","date_gmt":"2016-08-09T05:54:53","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/ongoing-optimization-locks\/"},"modified":"2023-06-26T12:47:06","modified_gmt":"2023-06-26T12:47:06","slug":"ongoing-optimization-locks","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/ongoing-optimization-locks\/","title":{"rendered":"Ongoing Optimization: Locks and Volatile with CppMem"},"content":{"rendered":"<p>The easiest way to solve the undefined behaviour in the post <a href=\"https:\/\/www.modernescpp.com\/index.php\/ongoing-optimization-2\">Ongoing Optimization: Unsynchronized access<\/a> is, to use a <a href=\"https:\/\/www.modernescpp.com\/index.php\/prefer-locks-to-mutexes\">lock.<\/a><\/p>\n<p><!--more--><\/p>\n<h2>Locks<\/h2>\n<p>Both threads <span style=\"font-family: courier new,courier;\">thread1<\/span> and <span style=\"font-family: courier new,courier;\">thread2<\/span> use the same mutex, wrapped in a <a href=\"https:\/\/www.modernescpp.com\/index.php\/prefer-locks-to-mutexes\">std::lock_guard.<\/a><\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<table>\n<tbody>\n<tr>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"> 1\r\n 2\r\n 3\r\n 4\r\n 5\r\n 6\r\n 7\r\n 8\r\n 9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20\r\n21\r\n22\r\n23\r\n24\r\n25\r\n26\r\n27\r\n28\r\n29<\/pre>\n<\/td>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #008000;\">\/\/ ongoingOptimizationLock.cpp<\/span>\r\n\r\n<span style=\"color: #0000ff;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;mutex&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;thread&gt;<\/span>\r\n\r\n<span style=\"color: #2b91af;\">int<\/span> x= 0;\r\n<span style=\"color: #2b91af;\">int<\/span> y= 0;\r\n\r\nstd::mutex mut;\r\n\r\n<span style=\"color: #2b91af;\">void<\/span> writing(){\r\n  std::lock_guard&lt;std::mutex&gt; guard(mut);\r\n  x= 2000;\r\n  y= 11;\r\n}\r\n\r\n<span style=\"color: #2b91af;\">void<\/span> reading(){\r\n  std::lock_guard&lt;std::mutex&gt; guard(mut);\r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"y: \"<\/span> &lt;&lt; y &lt;&lt; <span style=\"color: #a31515;\">\" \"<\/span>;\r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"x: \"<\/span> &lt;&lt; x &lt;&lt; std::endl;\r\n}\r\n\r\n<span style=\"color: #2b91af;\">int<\/span> main(){\r\n  std::<span style=\"color: #0000ff;\">thread<\/span> thread1(writing);\r\n  std::<span style=\"color: #0000ff;\">thread<\/span> thread2(reading);\r\n  thread1.join();\r\n  thread2.join();\r\n};\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Now, the program is well defined. Either <span style=\"font-family: courier new,courier;\">thread1<\/span> or <span style=\"font-family: courier new,courier;\">thread2<\/span> is running. Dependent on that, either both values are or aren&#8217;t set. So the following values for x and y are possible.<\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-4847\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/08\/sukzessiveOptimierungLocksEng.png\" alt=\"sukzessiveOptimierungLocksEng\" style=\"margin: 15px;\" width=\"288\" height=\"223\" \/><\/p>\n<h3>CppMem<\/h3>\n<p>I didn&#8217;t achieve it to use std::lock_guard in CppMem. Sorry. But if you achieve it, let me know.&nbsp;<\/p>\n<p>That was easy. But the synchronization with locks is too heavyweight. The freedom of the system to optimize the program is drastically reduced. There are only two possibilities. So, what should I do next? Of course, switch to atomics.&nbsp;<\/p>\n<p>There is the <span style=\"font-family: courier new,courier;\">volatile<\/span> keyword in C++. Let&#8217;s try it out.<\/p>\n<\/p>\n<h2>volatile<\/h2>\n<p>What has the keyword <span style=\"font-family: courier new,courier;\">volatile<\/span> in&nbsp;C# and Java with the keyword <span style=\"font-family: courier new,courier;\">volatile<\/span> in C++ in common? <strong>Nothing!<\/strong><\/p>\n<p>It&#8217;s so easy in C++.<\/p>\n<ol>\n<li><span style=\"font-family: courier new,courier;\">volatile<\/span> is for special objects on which optimized read or write operations are not allowed.<\/li>\n<li><span style=\"font-family: courier new,courier;\">std::atomic<\/span> defines atomic variables meant for thread-safe reading and writing.<\/li>\n<\/ol>\n<p>It&#8217;s so easy, but. The confusion starts exactly here. The keyword <span style=\"font-family: courier new,courier;\">volatile<\/span> in Java and C# means <span style=\"font-family: courier new,courier;\">std::atomic<\/span> in C++. Or, to say if differently. <span style=\"font-family: courier new,courier;\">volatile<\/span> has no multithreading semantics in C++.&nbsp;<\/p>\n<p><span style=\"font-family: courier new,courier;\">volatile<\/span> is typically used in embedded programming to denote objects, which can change independent of the regular program flow. These are for example objects, which represent an external device (memory-mapped I\/O). Because these objects can change independently of the regular program flow, their value will directly be written in the main memory. So there is no optimized storing in caches.<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<table>\n<tbody>\n<tr>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"> 1\r\n 2\r\n 3\r\n 4\r\n 5\r\n 6\r\n 7\r\n 8\r\n 9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20\r\n21\r\n22\r\n23\r\n24<\/pre>\n<\/td>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #008000;\">\/\/ ongoingOptimizationVolatile.cpp<\/span>\r\n\r\n<span style=\"color: #0000ff;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;thread&gt;<\/span>\r\n\r\n<span style=\"color: #0000ff;\">volatile<\/span> <span style=\"color: #2b91af;\">int<\/span> x= 0;\r\n<span style=\"color: #0000ff;\">volatile<\/span> <span style=\"color: #2b91af;\">int<\/span> y= 0;\r\n\r\n<span style=\"color: #2b91af;\">void<\/span> writing(){\r\n  x= 2000;\r\n  y= 11;\r\n}\r\n\r\n<span style=\"color: #2b91af;\">void<\/span> reading(){ \r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"y: \"<\/span> &lt;&lt; y &lt;&lt; <span style=\"color: #a31515;\">\" \"<\/span>;\r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"x: \"<\/span> &lt;&lt; x &lt;&lt; std::endl;\r\n}\r\n\r\n<span style=\"color: #2b91af;\">int<\/span> main(){\r\n  std::<span style=\"color: #0000ff;\">thread<\/span> thread1(writing);\r\n  std::<span style=\"color: #0000ff;\">thread<\/span> thread2(reading);\r\n  thread1.join();\r\n  thread2.join();\r\n};\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>&nbsp;<\/p>\n<p>So what does that mean for our small program from <a href=\"https:\/\/www.modernescpp.com\/index.php\/ongoing-optimization\">Ongoing Optimization<\/a> if I declare the int variables as <span style=\"font-family: courier new,courier;\">volatile<\/span>? I guess you know it. The program has a <a href=\"https:\/\/www.modernescpp.com\/index.php\/threads-sharing-data\">data race <\/a>on the variables x and y. So the program has undefined behavior and I can not reason about x and y.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-4840\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/08\/undefinedEng.png\" alt=\"undefinedEng\" style=\"margin: 15px;\" width=\"343\" height=\"240\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/08\/undefinedEng.png 343w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/08\/undefinedEng-300x210.png 300w\" sizes=\"auto, (max-width: 343px) 100vw, 343px\" \/><\/p>\n<h3>CppMem<\/h3>\n<p>volatile has no multithreading semantics. This shows CppMem unambiguously.<\/p>\n<p>&nbsp;<\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<table>\n<tbody>\n<tr>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"> 1\r\n 2\r\n 3\r\n 4\r\n 5\r\n 6\r\n 7\r\n 8\r\n 9\r\n10\r\n11\r\n12\r\n13<\/pre>\n<\/td>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #2b91af;\">int<\/span> main(){\r\n  <span style=\"color: #0000ff;\">volatile<\/span> <span style=\"color: #2b91af;\">int<\/span> x= 0; \r\n  <span style=\"color: #0000ff;\">volatile<\/span> <span style=\"color: #2b91af;\">int<\/span> y= 0;\r\n  {{{ { \r\n      x= 2000; \r\n      y= 11;\r\n      }\r\n  ||| {\r\n      y;\r\n      x;\r\n      } \r\n  }}}\r\n}\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The results are identical to the results of my analysis in the unsynchronized assessment with non-atomics. So you can read it here in my last post <a href=\"https:\/\/www.modernescpp.com\/index.php\/ongoing-optimization-2\">Ongoing Optimization: Unsynchronized access with CppMem.<\/a> It makes no difference if you use the variables x and y with or without the <span style=\"font-family: courier new,courier;\">volatile<\/span> qualifier.&nbsp; <a href=\"https:\/\/www.modernescpp.com\/index.php\/ongoing-optimization-2\"><\/a><\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>In the<a href=\"https:\/\/www.modernescpp.com\/index.php\/ongoing-optiimization-sequential-consistency-with-cppmem\"> next pos<\/a>t, I will make it right. I use atomics with sequential consistency.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The easiest way to solve the undefined behaviour in the post Ongoing Optimization: Unsynchronized access is, to use a lock.<\/p>\n","protected":false},"author":21,"featured_media":4847,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[369],"tags":[486,430,521,457],"class_list":["post-4848","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-multithreading-application","tag-cppmem","tag-lock","tag-ongoing-optimization","tag-volatile"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/4848","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/users\/21"}],"replies":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/comments?post=4848"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/4848\/revisions"}],"predecessor-version":[{"id":6957,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/4848\/revisions\/6957"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/4847"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=4848"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=4848"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=4848"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}