<!-- 
RSS generated by JIRA (9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66) at Thu Feb 08 05:33:53 UTC 2024

It is possible to restrict the fields that are returned in this document by specifying the 'field' parameter in your request.
For example, to request only the issue key and summary append 'field=key&field=summary' to the URL of your request.
-->
<rss version="0.92" >
<channel>
    <title>MongoDB Jira</title>
    <link>https://jira.mongodb.org</link>
    <description>This file is an XML representation of an issue</description>
    <language>en-us</language>    <build-info>
        <version>9.7.1</version>
        <build-number>970001</build-number>
        <build-date>13-04-2023</build-date>
    </build-info>


<item>
            <title>[SERVER-54570] Optimize costly atomic increment in Mutex uncontended stats count</title>
                <link>https://jira.mongodb.org/browse/SERVER-54570</link>
                <project id="10000" key="SERVER">Core Server</project>
                    <description>&lt;p&gt;The atomic integer increment in multi-core scenario is not cheap. The reason is that the atomic integer increment is a fully consistent RMW operation, which requires one core to obtain exclusive ownership of the cache line in its L1 cache. Details here: &lt;a href=&quot;https://fgiesen.wordpress.com/2014/08/18/atomics-and-contention/&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;https://fgiesen.wordpress.com/2014/08/18/atomics-and-contention/&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;The benchmarks show that while one thread uncontented atomic increment costs 40 ns, doing it concurrently with 4 cores costs 100 ns. Benchmarks: &lt;a href=&quot;https://travisdowns.github.io/blog/2020/07/06/concurrency-costs.html&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;https://travisdowns.github.io/blog/2020/07/06/concurrency-costs.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One might think that changing to relaxed memory order might help (doing like var.fetch_add(1, std::memory_order_relaxed); ) - but this is simply not true. The relaxed order means the memory barrier is relaxed relative to other memory locations, but this particular atomic increment is still full RMW and the performance penalty is the same, because the cache lines on all other cores must be invalidated.&lt;/p&gt;

&lt;p&gt;The simplest fix is to sacrifice consistency and do 2-step unrelated modification with relaxed order:&lt;/p&gt;

&lt;p&gt;    auto cur = counter.load(std::memory_order_relaxed);&lt;br/&gt;
    counter.store(cur + 1, std::memory_order_relaxed);&lt;/p&gt;

&lt;p&gt;We will sacrifice a bit of correctness for probably 5X to 10X performance improvement, or over 100 ns saving per Mutex lock.&lt;/p&gt;

&lt;p&gt;The code I&apos;m talking about is here:&lt;br/&gt;
&lt;a href=&quot;https://github.com/mongodb/mongo/blob/0fc5b56b12dbdc248556fdfa9da2f44479eac699/src/mongo/platform/mutex.cpp#L112&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;https://github.com/mongodb/mongo/blob/0fc5b56b12dbdc248556fdfa9da2f44479eac699/src/mongo/platform/mutex.cpp#L112&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We probably can keep fully consistent increment when the lock is contented (_onContendedLock()), because we incur substantial performance penalty anyway.&lt;/p&gt;


&lt;p&gt;Variant 2. The book &lt;a href=&quot;https://mirrors.edge.kernel.org/pub/linux/kernel/people/paulmck/perfbook/perfbook.html&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;Is Parallel Programming Hard, And, If So, What Can You Do About It?&lt;/a&gt; has the whole chapter 5 about global counters, and shows that worst case cost could go up to milliseconds. The fastest solution they propose in chapter 5.2.4 is eventually consistent thread-local array of counters.&lt;/p&gt;

&lt;p&gt;By my opinion thread-local could be too cumbersome to implement because of all annoying registration code, and potentially huge number of counters, but there is a much simpler alternative (not discussed online but obvious) - sharded counter with random bucketing. The bucketing pick should be made extremely cheap. By my opinion, use TSC (time stamp counter). The portable implementation example &lt;a href=&quot;https://stackoverflow.com/questions/13772567/how-to-get-the-cpu-cycle-count-in-x86-64-from-c&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;here&lt;/a&gt;. Then just calculate (TSC % nBuckets) to get a random bucket each time. A periodic process (or just a reader) should swipe all accumulated counters into single integer, and reset all counters back to zero. A reader can always check the first counter - if the value is very small (&amp;lt;10) do not swipe and get a slightly stale result instead.&lt;/p&gt;</description>
                <environment></environment>
        <key id="1623537">SERVER-54570</key>
            <summary>Optimize costly atomic increment in Mutex uncontended stats count</summary>
                <type id="4" iconUrl="https://jira.mongodb.org/secure/viewavatar?size=xsmall&amp;avatarId=14710&amp;avatarType=issuetype">Improvement</type>
                                            <priority id="3" iconUrl="https://jira.mongodb.org/images/icons/priorities/major.svg">Major - P3</priority>
                        <status id="6" iconUrl="https://jira.mongodb.org/images/icons/statuses/closed.png" description="The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.">Closed</status>
                    <statusCategory id="3" key="done" colorName="success"/>
                                    <resolution id="2">Won&apos;t Fix</resolution>
                                        <assignee username="backlog-server-servicearch">Backlog - Service Architecture</assignee>
                                    <reporter username="andrew.shuvalov@mongodb.com">Andrew Shuvalov</reporter>
                        <labels>
                    </labels>
                <created>Mon, 15 Feb 2021 01:05:24 +0000</created>
                <updated>Tue, 6 Dec 2022 01:34:38 +0000</updated>
                            <resolved>Tue, 23 Feb 2021 18:49:44 +0000</resolved>
                                                                                        <votes>0</votes>
                                    <watches>4</watches>
                                                                                                                <comments>
                            <comment id="3616901" author="JIRAUSER1256988" created="Tue, 16 Feb 2021 14:17:02 +0000"  >&lt;p&gt;I&apos;ve realized that different Mutexes do not share same stat counter so what I described above is not necessary at this stage. I actually would like to have a global lock contention monitor as part of better feedback loop on our thread pool sizes but this is outside of the scope of one ticket. I actually plan to make a presentation about thread pool optimization this Friday 2/19 at 10 am, where I will touch this topic.&lt;/p&gt;

&lt;p&gt;It looks like even though we track per-muter lock contention we don&apos;t do anything about it, I don&apos;t see any code invoking `getDiagnosticListenerState()`. Looks like unfinished effort in the right direction. &lt;/p&gt;

&lt;p&gt;Please read the ticket description just for your information and feel free to close it with &quot;will not fix&quot;, and please check at my presentation 2/19.&lt;/p&gt;</comment>
                    </comments>
                    <attachments>
                    </attachments>
                <subtasks>
                    </subtasks>
                <customfields>
                                                <customfield id="customfield_10050" key="com.atlassian.jira.toolkit:comments">
                        <customfieldname># Replies</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>1.0</customfieldvalue>
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                <customfield id="customfield_12751" key="com.atlassian.jira.plugin.system.customfieldtypes:multiselect">
                        <customfieldname>Assigned Teams</customfieldname>
                        <customfieldvalues>
                                <customfieldvalue key="25132"><![CDATA[Service Arch]]></customfieldvalue>
    
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                <customfield id="customfield_10052" key="com.atlassian.jira.toolkit:dayslastcommented">
                        <customfieldname>Days since reply</customfieldname>
                        <customfieldvalues>
                                        2 years, 51 weeks, 1 day ago
    
                        </customfieldvalues>
                    </customfield>
                                                                <customfield id="customfield_18254" key="com.onresolve.jira.groovy.groovyrunner:scripted-field">
                        <customfieldname>Dependencies</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue><![CDATA[]]></customfieldvalue>


                        </customfieldvalues>
                    </customfield>
                                                                <customfield id="customfield_15850" key="com.atlassian.jira.plugins.jira-development-integration-plugin:devsummary">
                        <customfieldname>Development</customfieldname>
                        <customfieldvalues>
                            
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        <customfield id="customfield_10057" key="com.atlassian.jira.toolkit:lastusercommented">
                        <customfieldname>Last comment by Customer</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>true</customfieldvalue>
                        </customfieldvalues>
                    </customfield>
                                                                                            <customfield id="customfield_10056" key="com.atlassian.jira.toolkit:lastupdaterorcommenter">
                        <customfieldname>Last commenter</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>alexander.golin@mongodb.com</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                <customfield id="customfield_11151" key="com.atlassian.jira.toolkit:LastCommentDate">
                        <customfieldname>Last public comment date</customfieldname>
                        <customfieldvalues>
                            2 years, 51 weeks, 1 day ago
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                    <customfield id="customfield_10051" key="com.atlassian.jira.toolkit:participants">
                        <customfieldname>Participants</customfieldname>
                        <customfieldvalues>
                                        <customfieldvalue>andrew.shuvalov@mongodb.com</customfieldvalue>
            <customfieldvalue>backlog-server-servicearch</customfieldvalue>
    
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                        <customfield id="customfield_14254" key="com.pyxis.greenhopper.jira:gh-lexo-rank">
                        <customfieldname>Product Rank</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>1|hyv5pj:</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                <customfield id="customfield_12550" key="com.pyxis.greenhopper.jira:gh-lexo-rank">
                        <customfieldname>Rank</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>2|hygnfb:</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                <customfield id="customfield_10558" key="com.pyxis.greenhopper.jira:gh-global-rank">
                        <customfieldname>Rank (Obsolete)</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>9223372036854775807</customfieldvalue>
                        </customfieldvalues>
                    </customfield>
                                                                                            <customfield id="customfield_23361" key="com.onresolve.jira.groovy.groovyrunner:scripted-field">
                        <customfieldname>Requested By</customfieldname>
                        <customfieldvalues>
                                

                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                <customfield id="customfield_10053" key="com.atlassian.jira.ext.charting:timeinstatus">
                        <customfieldname>Time In Status</customfieldname>
                        <customfieldvalues>
                            
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                        <customfield id="customfield_22870" key="com.onresolve.jira.groovy.groovyrunner:scripted-field">
                        <customfieldname>Triagers</customfieldname>
                        <customfieldvalues>
                                

                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                    <customfield id="customfield_14350" key="com.pyxis.greenhopper.jira:gh-lexo-rank">
                        <customfieldname>serverRank</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>1|hyuryn:</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                    </customfields>
    </item>
</channel>
</rss>