{"id":5410,"date":"2018-03-23T20:55:18","date_gmt":"2018-03-23T20:55:18","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-rules-to-performance\/"},"modified":"2023-06-26T11:54:15","modified_gmt":"2023-06-26T11:54:15","slug":"c-core-guidelines-rules-to-performance","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-rules-to-performance\/","title":{"rendered":"C++ Core Guidelines: Rules about Performance"},"content":{"rendered":"<p>Before I write about the rules of performance, I will do a straightforward job. Accessing the elements of a container one by one.<\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5408\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/03\/cheetah.jpg\" alt=\"cheetah\" width=\"640\" height=\"407\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/03\/cheetah.jpg 640w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/03\/cheetah-300x191.jpg 300w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/p>\n<p>Here is the last rule for arithmetic.<\/p>\n<h3><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Res-subscripts\">ES.107: Don\u2019t use <code class=\"highlighter-rouge no-highlight\">unsigned<\/code> for subscripts, prefer <code class=\"highlighter-rouge no-highlight\">gsl::index<\/code><\/a><\/h3>\n<p>Did I say that this is a simple job? Honestly, this was a lie.&nbsp; See what can go wrong. Here is an example of a <span style=\"font-family: 'courier new', courier;\">std::vector.<\/span><\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\">vector<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span> vec <span style=\"color: #555555;\">=<\/span> <span style=\"color: #0099ff; font-style: italic;\">\/*...*\/<\/span>;\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #007788; font-weight: bold;\">int<\/span> i <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">0<\/span>; i <span style=\"color: #555555;\">&lt;<\/span> vec.size(); i <span style=\"color: #555555;\">+=<\/span> <span style=\"color: #ff6600;\">2<\/span>)                    <span style=\"color: #0099ff; font-style: italic;\">\/\/ may not be big enough (2)<\/span>\r\n    cout <span style=\"color: #555555;\">&lt;&lt;<\/span> vec[i] <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n<span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #007788; font-weight: bold;\">unsigned<\/span> i <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">0<\/span>; i <span style=\"color: #555555;\">&lt;<\/span> vec.size(); i <span style=\"color: #555555;\">+=<\/span> <span style=\"color: #ff6600;\">2<\/span>)               <span style=\"color: #0099ff; font-style: italic;\">\/\/ risk wraparound       (3)<\/span>\r\n    cout <span style=\"color: #555555;\">&lt;&lt;<\/span> vec[i] <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n<span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #006699; font-weight: bold;\">auto<\/span> i <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">0<\/span>; i <span style=\"color: #555555;\">&lt;<\/span> vec.size(); i <span style=\"color: #555555;\">+=<\/span> <span style=\"color: #ff6600;\">2<\/span>)                   <span style=\"color: #0099ff; font-style: italic;\">\/\/ may not be big enough (2)<\/span>\r\n    cout <span style=\"color: #555555;\">&lt;&lt;<\/span> vec[i] <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n<span style=\"color: #006699; font-weight: bold;\">for<\/span> (vector<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;::<\/span>size_type i <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">0<\/span>; i <span style=\"color: #555555;\">&lt;<\/span> vec.size(); i <span style=\"color: #555555;\">+=<\/span> <span style=\"color: #ff6600;\">2<\/span>) <span style=\"color: #0099ff; font-style: italic;\">\/\/ verbose               (1)<\/span>\r\n    cout <span style=\"color: #555555;\">&lt;&lt;<\/span> vec[i] <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n<span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #006699; font-weight: bold;\">auto<\/span> i <span style=\"color: #555555;\">=<\/span> vec.size()<span style=\"color: #555555;\">-<\/span><span style=\"color: #ff6600;\">1<\/span>; i <span style=\"color: #555555;\">&gt;=<\/span> <span style=\"color: #ff6600;\">0<\/span>; i <span style=\"color: #555555;\">-=<\/span> <span style=\"color: #ff6600;\">2<\/span>)                <span style=\"color: #0099ff; font-style: italic;\">\/\/ bug                   (4) <\/span>\r\n    cout <span style=\"color: #555555;\">&lt;&lt;<\/span> vec[i] <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n<span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #007788; font-weight: bold;\">int<\/span> i <span style=\"color: #555555;\">=<\/span> vec.size()<span style=\"color: #555555;\">-<\/span><span style=\"color: #ff6600;\">1<\/span>; i <span style=\"color: #555555;\">&gt;=<\/span> <span style=\"color: #ff6600;\">0<\/span>; i <span style=\"color: #555555;\">-=<\/span> <span style=\"color: #ff6600;\">2<\/span>)                 <span style=\"color: #0099ff; font-style: italic;\">\/\/ may not be big enough (2)<\/span>\r\n    cout <span style=\"color: #555555;\">&lt;&lt;<\/span> vec[i] <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Scary? Right! Only line (1) is correct. It may happen in line (2) that the variable <span style=\"font-family: courier\\ new, courier;\">i i<\/span>s too small. The result may be an overflow. This will not hold for line (3) because <span style=\"font-family: courier\\ new, courier;\">i<\/span> is <span style=\"font-family: courier\\ new, courier;\">unsigned<\/span>. Instead of an overflow, you will get a modulo operation. In my last post, I wrote about this nice effect: <a href=\"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-rules-to-statements-and-arithmetic-rules\">C++ Core Guidelines: Rules to Statements and Arithmetic<\/a>. To be more specific, it was ruled ES.106.<\/p>\n<p>Line 4 is left. This is my favorite one. What is the problem? The problem is that <span style=\"font-family: courier\\ new, courier;\">vec.size()<\/span> is of type <span style=\"font-family: courier\\ new, courier;\">std::size_t. std::size_t<\/span> is an <span style=\"font-family: courier\\ new, courier;\">unsigned type <\/span>and can not represent negative numbers. Imagine what would happen if the vector was empty. This means that <span style=\"font-family: courier\\ new, courier;\">vec.size() -1<\/span> is &#8211;<span style=\"font-family: courier\\ new, courier;\">1. <\/span>The result is that we get the maximum value of type <span style=\"font-family: courier\\ new, courier;\">std::size_t.<\/span><\/p>\n<p>The program<span style=\"font-family: courier\\ new, courier;\"> index.cpp<\/span> shows this strange behavior.<\/p>\n<p>&nbsp;<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ index.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;vector&gt;<\/span>\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>(){\r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>vector<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span> vec{};\r\n    \r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> ind1 <span style=\"color: #555555;\">=<\/span> vec.size() <span style=\"color: #555555;\">-<\/span> <span style=\"color: #ff6600;\">1<\/span> ;\r\n    <span style=\"color: #007788; font-weight: bold;\">int<\/span> ind2 <span style=\"color: #555555;\">=<\/span> vec.size() <span style=\"color: #555555;\">-<\/span><span style=\"color: #ff6600;\">1<\/span> ;\r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"ind1: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> ind1 <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"ind2: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> ind2 <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    \r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>&nbsp;And here is the output:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5409\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/03\/index.png\" alt=\"index\" width=\"382\" height=\"225\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/03\/index.png 382w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/03\/index-300x177.png 300w\" sizes=\"auto, (max-width: 382px) 100vw, 382px\" \/><\/p>\n<p>The guidelines suggest that the variable i should be of type <span style=\"font-family: courier\\ new, courier;\">gsl::index.<\/span><\/p>\n<p>&nbsp;<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #006699; font-weight: bold;\">for<\/span> (gsl<span style=\"color: #555555;\">::<\/span>index i <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">0<\/span>; i <span style=\"color: #555555;\">&lt;<\/span> vec.size(); i <span style=\"color: #555555;\">+=<\/span> <span style=\"color: #ff6600;\">2<\/span>)             <span style=\"color: #0099ff; font-style: italic;\">\/\/ ok<\/span>\r\n    cout <span style=\"color: #555555;\">&lt;&lt;<\/span> vec[i] <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n<span style=\"color: #006699; font-weight: bold;\">for<\/span> (gsl<span style=\"color: #555555;\">::<\/span>index i <span style=\"color: #555555;\">=<\/span> vec.size()<span style=\"color: #555555;\">-<\/span><span style=\"color: #ff6600;\">1<\/span>; i <span style=\"color: #555555;\">&gt;=<\/span> <span style=\"color: #ff6600;\">0<\/span>; i <span style=\"color: #555555;\">-=<\/span> <span style=\"color: #ff6600;\">2<\/span>)          <span style=\"color: #0099ff; font-style: italic;\">\/\/ ok<\/span>\r\n    cout <span style=\"color: #555555;\">&lt;&lt;<\/span> vec[i] <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>If this is not an option, use the type <span style=\"font-family: courier\\ new, courier;\">std::vector&lt;int&gt;::size_type<\/span> for i.<\/p>\n<p>Performance is the domain of C++! Right? Therefore I was pretty curious to write about the rules for performance. But this is hardly possible because most of the rules lack beef. They consist of a title and a reason. Sometimes even the reason is missing.<\/p>\n<p>Anyway. Here are the first rules:<\/p>\n<ul>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rper-reason\">Per.1: Don\u2019t optimize without reason<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rper-Knuth\">Per.2: Don\u2019t optimize prematurely<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rper-critical\">Per.3: Don\u2019t optimize something that\u2019s not performance critical<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rper-simple\">Per.4: Don\u2019t assume that complicated code is necessarily faster than simple code<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rper-low\">Per.5: Don\u2019t assume that low-level code is necessarily faster than high-level code<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rper-measure\">Per.6: Don\u2019t make claims about performance without measurements<\/a><\/li>\n<\/ul>\n<p>&nbsp;Instead of writing general remarks to general rules, I will provide a few examples of these rules. Let&#8217;s start with rules Per.4, Per.5, and Per.6<\/p>\n<\/p>\n<h3><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rper-simple\">Per.4: Don\u2019t assume that complicated code is necessarily faster than simple code<\/a><\/h3>\n<h3><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rper-low\">Per.5: Don\u2019t assume that low-level code is necessarily faster than high-level code<\/a><\/h3>\n<h3><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rper-measure\">Per.6: Don\u2019t make claims about performance without measurements<\/a><\/h3>\n<p>&nbsp;<\/p>\n<p>Before I continue to write, I have to make a disclaimer: I do not recommend using the singleton pattern. I only want to show that complicated and low-level code does not always pay off. To prove my point, I have to measure the performance.<\/p>\n<p>Long ago, I wrote about the thread-safe initialization of the singleton pattern in my post: <a href=\"https:\/\/www.modernescpp.com\/index.php\/thread-safe-initialization-of-a-singleton\">Thread-safe initialization of a singleton<\/a>. The key idea of the post was to invoke the singleton pattern 40.000.000 times from four threads and measure the execution time. The singleton pattern will be initialized lazily; therefore, the first call has to initialize it.<\/p>\n<p>I implemented the singleton pattern in various ways. I did it with a <span style=\"font-family: courier\\ new, courier;\">std::lock_guard and<\/span>&nbsp;the function <span style=\"font-family: courier\\ new, courier;\">std::call_once<\/span> in combination with the <span style=\"font-family: courier\\ new, courier;\">std::once_flag<\/span>. I did it with a static variable. I even used atomics and broke the sequential consistency for performance reasons.<\/p>\n<p>To make my pointer clear. I want to show you the most straightforward and challenging implementation.<\/p>\n<p>The easiest implementation is the so-called Meyers singleton. It is thread-safe because the C++11-standard guarantees that a static variable with block scope will be initialized in a thread-safe way.<\/p>\n<p>&nbsp;<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ singletonMeyers.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;chrono&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;future&gt;<\/span>\r\n\r\nconstexpr <span style=\"color: #006699; font-weight: bold;\">auto<\/span> tenMill<span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">10000000<\/span>;\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">MySingleton<\/span>{\r\n<span style=\"color: #9999ff;\">public:<\/span>\r\n  <span style=\"color: #006699; font-weight: bold;\">static<\/span> MySingleton<span style=\"color: #555555;\">&amp;<\/span> getInstance(){\r\n    <span style=\"color: #006699; font-weight: bold;\">static<\/span> MySingleton instance;                         <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ volatile int dummy{};<\/span>\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> instance;\r\n  }\r\n<span style=\"color: #9999ff;\">private:<\/span>\r\n  MySingleton()<span style=\"color: #555555;\">=<\/span> <span style=\"color: #006699; font-weight: bold;\">default<\/span>;\r\n  <span style=\"color: #555555;\">~<\/span>MySingleton()<span style=\"color: #555555;\">=<\/span> <span style=\"color: #006699; font-weight: bold;\">default<\/span>;\r\n  MySingleton(<span style=\"color: #006699; font-weight: bold;\">const<\/span> MySingleton<span style=\"color: #555555;\">&amp;<\/span>)<span style=\"color: #555555;\">=<\/span> <span style=\"color: #006699; font-weight: bold;\">delete<\/span>;\r\n  MySingleton<span style=\"color: #555555;\">&amp;<\/span> <span style=\"color: #006699; font-weight: bold;\">operator<\/span><span style=\"color: #555555;\">=<\/span>(<span style=\"color: #006699; font-weight: bold;\">const<\/span> MySingleton<span style=\"color: #555555;\">&amp;<\/span>)<span style=\"color: #555555;\">=<\/span> <span style=\"color: #006699; font-weight: bold;\">delete<\/span>;\r\n\r\n};\r\n\r\nstd<span style=\"color: #555555;\">::<\/span>chrono<span style=\"color: #555555;\">::<\/span>duration<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">double<\/span><span style=\"color: #555555;\">&gt;<\/span> getTime(){\r\n\r\n  <span style=\"color: #006699; font-weight: bold;\">auto<\/span> begin<span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span>chrono<span style=\"color: #555555;\">::<\/span>system_clock<span style=\"color: #555555;\">::<\/span>now();\r\n  <span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #007788; font-weight: bold;\">size_t<\/span> i<span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">0<\/span>; i <span style=\"color: #555555;\">&lt;<\/span> tenMill; <span style=\"color: #555555;\">++<\/span>i){\r\n      MySingleton<span style=\"color: #555555;\">::<\/span>getInstance();                        <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\r\n  }\r\n  <span style=\"color: #006699; font-weight: bold;\">return<\/span> std<span style=\"color: #555555;\">::<\/span>chrono<span style=\"color: #555555;\">::<\/span>system_clock<span style=\"color: #555555;\">::<\/span>now() <span style=\"color: #555555;\">-<\/span> begin;\r\n  \r\n};\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>(){\r\n                                                         <span style=\"color: #0099ff; font-style: italic;\"><\/span>\r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> fut1<span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span>async(std<span style=\"color: #555555;\">::<\/span>launch<span style=\"color: #555555;\">::<\/span>async,getTime);\r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> fut2<span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span>async(std<span style=\"color: #555555;\">::<\/span>launch<span style=\"color: #555555;\">::<\/span>async,getTime);\r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> fut3<span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span>async(std<span style=\"color: #555555;\">::<\/span>launch<span style=\"color: #555555;\">::<\/span>async,getTime);\r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> fut4<span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span>async(std<span style=\"color: #555555;\">::<\/span>launch<span style=\"color: #555555;\">::<\/span>async,getTime);\r\n    \r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> total<span style=\"color: #555555;\">=<\/span> fut1.get() <span style=\"color: #555555;\">+<\/span> fut2.get() <span style=\"color: #555555;\">+<\/span> fut3.get() <span style=\"color: #555555;\">+<\/span> fut4.get();\r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> total.count() <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Line (1) uses the&nbsp;guarantee of the C++11-runtime that the singleton will be initialized in a thread-safe way. Each of the four threads in the main function invokes 10 million times the singleton inline (2). In total, this makes 40 million calls.<\/p>\n<p>But I can do better. This time I use atomics to make the singleton pattern thread-safe. My implementation is based on the infamous <a href=\"https:\/\/en.wikipedia.org\/wiki\/Double-checked_locking\">double-checked locking pattern<\/a>. For the sake of simplicity, I will only show the implementation of the class&nbsp;<span style=\"font-family: courier\\ new, courier;\">MySingleton<\/span>.<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">MySingleton<\/span>{\r\n<span style=\"color: #9999ff;\">public:<\/span>\r\n  <span style=\"color: #006699; font-weight: bold;\">static<\/span> MySingleton<span style=\"color: #555555;\">*<\/span> getInstance(){\r\n    MySingleton<span style=\"color: #555555;\">*<\/span> sin<span style=\"color: #555555;\">=<\/span> instance.load(std<span style=\"color: #555555;\">::<\/span>memory_order_acquire);\r\n    <span style=\"color: #006699; font-weight: bold;\">if<\/span> ( <span style=\"color: #555555;\">!<\/span>sin ){\r\n      std<span style=\"color: #555555;\">::<\/span>lock_guard<span style=\"color: #555555;\">&lt;<\/span>std<span style=\"color: #555555;\">::<\/span>mutex<span style=\"color: #555555;\">&gt;<\/span> myLock(myMutex);\r\n      sin<span style=\"color: #555555;\">=<\/span> instance.load(std<span style=\"color: #555555;\">::<\/span>memory_order_relaxed);\r\n      <span style=\"color: #006699; font-weight: bold;\">if<\/span>( <span style=\"color: #555555;\">!<\/span>sin ){\r\n        sin<span style=\"color: #555555;\">=<\/span> <span style=\"color: #006699; font-weight: bold;\">new<\/span> MySingleton();\r\n        instance.store(sin,std<span style=\"color: #555555;\">::<\/span>memory_order_release);\r\n      }\r\n    }   \r\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ volatile int dummy{};<\/span>\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> sin;\r\n  }\r\n<span style=\"color: #9999ff;\">private:<\/span>\r\n  MySingleton()<span style=\"color: #555555;\">=<\/span> <span style=\"color: #006699; font-weight: bold;\">default<\/span>;\r\n  <span style=\"color: #555555;\">~<\/span>MySingleton()<span style=\"color: #555555;\">=<\/span> <span style=\"color: #006699; font-weight: bold;\">default<\/span>;\r\n  MySingleton(<span style=\"color: #006699; font-weight: bold;\">const<\/span> MySingleton<span style=\"color: #555555;\">&amp;<\/span>)<span style=\"color: #555555;\">=<\/span> <span style=\"color: #006699; font-weight: bold;\">delete<\/span>;\r\n  MySingleton<span style=\"color: #555555;\">&amp;<\/span> <span style=\"color: #006699; font-weight: bold;\">operator<\/span><span style=\"color: #555555;\">=<\/span>(<span style=\"color: #006699; font-weight: bold;\">const<\/span> MySingleton<span style=\"color: #555555;\">&amp;<\/span>)<span style=\"color: #555555;\">=<\/span> <span style=\"color: #006699; font-weight: bold;\">delete<\/span>;\r\n\r\n  <span style=\"color: #006699; font-weight: bold;\">static<\/span> std<span style=\"color: #555555;\">::<\/span>atomic<span style=\"color: #555555;\">&lt;<\/span>MySingleton<span style=\"color: #555555;\">*&gt;<\/span> instance;\r\n  <span style=\"color: #006699; font-weight: bold;\">static<\/span> std<span style=\"color: #555555;\">::<\/span>mutex myMutex;\r\n};\r\n\r\n\r\nstd<span style=\"color: #555555;\">::<\/span>atomic<span style=\"color: #555555;\">&lt;<\/span>MySingleton<span style=\"color: #555555;\">*&gt;<\/span> MySingleton<span style=\"color: #555555;\">::<\/span>instance;\r\nstd<span style=\"color: #555555;\">::<\/span>mutex MySingleton<span style=\"color: #555555;\">::<\/span>myMutex;\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Maybe you heard that the&nbsp;<a href=\"http:\/\/wiki.c2.com\/?DoubleCheckedLockingIsBroken\">double-checked locking pattern is broken.&nbsp;<\/a> Of course, not my implementation! If you don&#8217;t believe me, prove it to me. First, you have to study the memory model, think about the acquire-release semantic, and think about the synchronization and ordering constraint that will hold in this implementation. This is not an easy job. But you know, highly sophisticated code pays off.<\/p>\n<p>Damn. I forgot the rule Per.6: Here are the performance numbers for the Meyers singleton on Linux. I compiled the program with maximum optimization. The numbers on Windows were in the same ballpark.<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-4866\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/08\/singletonMeyers_opt.png\" alt=\"singletonMeyers opt\" width=\"640\" height=\"145\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/08\/singletonMeyers_opt.png 640w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/08\/singletonMeyers_opt-300x68.png 300w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/p>\n<p>Now I&#8217;m curious. What are the numbers for my highly sophisticated code? Let&#8217;s see which performance we will get with atomics.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-4882\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/08\/singletonAcquireRelease_opt.png\" alt=\"singletonAcquireRelease opt\" width=\"640\" height=\"145\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/08\/singletonAcquireRelease_opt.png 640w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/08\/singletonAcquireRelease_opt-300x68.png 300w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/p>\n<p>50% percent slower! 50% percent slower, and we don&#8217;t even know if the implementation is correct. Disclaimer: The implementation is correct.<\/p>\n<p>Indeed, the Meyers singleton was the fastest and easiest way to get a&nbsp;thread-safe implementation of the singleton pattern. If you are curious about the details, read my post: <a href=\"https:\/\/www.modernescpp.com\/index.php\/thread-safe-initialization-of-a-singleton\">Thread-safe initialization of a singleton<\/a>.<\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>There are more than 10 rules to performance left in the guidelines. Although it is quite challenging to write about such general rules for my next post, I have<a href=\"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-more-rules-to-performance\"> <\/a>a few ideas in mind.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Before I write about the rules of performance, I will do a straightforward job. Accessing the elements of a container one by one.<\/p>\n","protected":false},"author":21,"featured_media":5408,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[372],"tags":[470],"class_list":["post-5410","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-modern-c","tag-performance"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5410","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=5410"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5410\/revisions"}],"predecessor-version":[{"id":6834,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5410\/revisions\/6834"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5408"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5410"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5410"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5410"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}