Boost C++ Libraries: Ticket #7906: Very bad performance of generic implementation of shared_mutex on windows https://svn.boost.org/trac10/ticket/7906 <p> Now (including boost 1.52) shared_mutex on win uses very efficient implementation. But after upgrade from boost 1.44 to boost 1.52 I have found what some base scenarios stopped working. For example: <a class="ext-link" href="https://svn.boost.org/trac/boost/ticket/7755"><span class="icon">​</span>https://svn.boost.org/trac/boost/ticket/7755</a>. Vicente asked me to try define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN to try generic implementation of shared_mutex. And problem 7755 was resolved as "will be fixed by generic implementation which will be default in boost 1.53". Some time later I have found one more broken in 1.52 base scenario when using upgrade_lock. The problem is the same as <a class="ext-link" href="https://svn.boost.org/trac/boost/ticket/7720"><span class="icon">​</span>https://svn.boost.org/trac/boost/ticket/7720</a>. I have switched to the generic implementation in my second project and problem seems to be resolved. But when I have found some delays in my time-critical code which uses shared_mutex'es (all 3 kinds of locks is used: shared, unique and upgrade). I have made some performance analysis and found what the problem is in new shared_mutex. On boost 1.44 some code is performed for 0.44s (real CPU time as shown in VTune) and with boost 1.52 with generic implementation the same code is performed for 1.52s. </p> <p> For now I have rewrite my code to don't use upgrade_lock and compiled it with win32 implementation of shared_mutex. The main problem I see is this slow implementation will be default in the boost 1.53. I believe this will impact many boost users and this issue will be raised anyway when 1.53 will be released. </p> <p> I have made a simple test for you: </p> <pre class="wiki">#include "stdafx.h" using namespace boost; shared_mutex mtx; const int cycles = 10000; void shared() { int cycle(0); while (++cycle &lt; cycles) { shared_lock&lt;shared_mutex&gt; lock(mtx); } } void unique() { int cycle(0); while (++cycle &lt; cycles) { unique_lock&lt;shared_mutex&gt; lock(mtx); } } int main() { boost::chrono::high_resolution_clock clock; boost::chrono::high_resolution_clock::time_point s1 = clock.now(); thread t0(shared); thread t1(shared); thread t2(unique); t0.join(); t1.join(); t2.join(); boost::chrono::high_resolution_clock::time_point f1 = clock.now(); std::cout &lt;&lt; "Time spent:" &lt;&lt; (f1 - s1) &lt;&lt; std::endl; return 0; } </pre><p> The results (I made 10 runs of each exe, below is average results):<br /> win32 implementation: Time spent:3450301 nanoseconds<br /> generic implementation: Time spent:12010409 nanoseconds </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/7906 Trac 1.4.3 Andrey <nikolay@…> Sat, 19 Jan 2013 07:38:58 GMT <link>https://svn.boost.org/trac10/ticket/7906#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7906#comment:1</guid> <description> <p> My proposal is to fix bugs 7720 and 7755 in win32 implementation and leave it default in boost 1.53. </p> </description> <category>Ticket</category> </item> <item> <author>Andrey <nikolay@…></author> <pubDate>Sat, 19 Jan 2013 07:40:17 GMT</pubDate> <title>component, severity changed; keywords, owner set https://svn.boost.org/trac10/ticket/7906#comment:2 https://svn.boost.org/trac10/ticket/7906#comment:2 <ul> <li><strong>keywords</strong> thread shared_mutex added </li> <li><strong>owner</strong> set to <span class="trac-author">Anthony Williams</span> </li> <li><strong>component</strong> <span class="trac-field-old">None</span> → <span class="trac-field-new">thread</span> </li> <li><strong>severity</strong> <span class="trac-field-old">Problem</span> → <span class="trac-field-new">Regression</span> </li> </ul> Ticket viboes Sat, 19 Jan 2013 10:44:43 GMT <link>https://svn.boost.org/trac10/ticket/7906#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7906#comment:3</guid> <description> <p> I don't know if you are aware but BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN will not be defined by default in 1.53. </p> <p> Anyway, I have reopened the tickets that were closed as duplicated <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/7720" title="#7720: Bugs: exception lock_error while intensive locking/unlocking of mutex (closed: fixed)">#7720</a> and <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/7755" title="#7755: Bugs: Thread: deadlock with shared_mutex on Windows (closed: fixed)">#7755</a>. </p> <p> BTW, thanks for providing a performance test. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>viboes</dc:creator> <pubDate>Sat, 19 Jan 2013 11:21:13 GMT</pubDate> <title>owner, status, severity changed https://svn.boost.org/trac10/ticket/7906#comment:4 https://svn.boost.org/trac10/ticket/7906#comment:4 <ul> <li><strong>owner</strong> changed from <span class="trac-author">Anthony Williams</span> to <span class="trac-author">viboes</span> </li> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">assigned</span> </li> <li><strong>severity</strong> <span class="trac-field-old">Regression</span> → <span class="trac-field-new">Optimization</span> </li> </ul> <p> Moved to optimization as BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN is not defined by default. </p> Ticket viboes Sun, 27 Jan 2013 21:14:57 GMT attachment set https://svn.boost.org/trac10/ticket/7906 https://svn.boost.org/trac10/ticket/7906 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">7906_it.patch</span> </li> </ul> Ticket viboes Sun, 27 Jan 2013 21:19:54 GMT <link>https://svn.boost.org/trac10/ticket/7906#comment:5 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7906#comment:5</guid> <description> <p> One of the factors making the difference is that the win32 doesn't mask the interruption. </p> <p> Once the attached patch is applied the measures are closer even if the win32 is yet better. </p> <p> Please could you try the attached patch on trunk? BTW, give the measure for the best sample as done on the performance test example/perf_shared_mutex.cpp </p> </description> <category>Ticket</category> </item> <item> <dc:creator>viboes</dc:creator> <pubDate>Thu, 07 Feb 2013 18:50:18 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/7906#comment:6 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7906#comment:6</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/7906#comment:5" title="Comment 5">viboes</a>: </p> <blockquote class="citation"> <p> One of the factors making the difference is that the win32 doesn't mask the interruption. </p> <p> Once the attached patch is applied the measures are closer even if the win32 is yet better. </p> <p> Please could you try the attached patch on trunk? BTW, give the measure for the best sample as done on the performance test example/perf_shared_mutex.cpp </p> </blockquote> <p> Andrey, any news on the measures? </p> </description> <category>Ticket</category> </item> <item> <author>Andrey <nikolay@…></author> <pubDate>Fri, 08 Feb 2013 12:32:20 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/7906#comment:7 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7906#comment:7</guid> <description> <p> I am going to test you patch on next week. Sorry for the delay. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>viboes</dc:creator> <pubDate>Sat, 09 Feb 2013 14:00:09 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/7906#comment:8 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7906#comment:8</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/7906#comment:7" title="Comment 7">Andrey &lt;nikolay@…&gt;</a>: </p> <blockquote class="citation"> <p> I am going to test you patch on next week. Sorry for the delay. </p> </blockquote> <p> After thinking a little bit more on this subject, I'm not sure shared_mutex should be an interruption point or not. With the pthread implementation most of the operations are interruption points as they use condition_variables, but the win32 implementation don't use condition_variables. What do you think? </p> <p> In any case the patch is incomplete as it only disable interrupts, but doesn't adds calls to this_thread::interruption_point(). </p> <p> The test I also did is to compile without interruptions. Please could you give the performances when you enable/disable interruptions (BOOST_THREAD_PROVIDES_INTERRUPTIONS/BOOST_THREAD_DONT_PROVIDE_INTERRUPTIONS)? </p> </description> <category>Ticket</category> </item> <item> <author>Andrey <nikolay@…></author> <pubDate>Tue, 12 Feb 2013 05:01:08 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/7906#comment:9 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7906#comment:9</guid> <description> <p> Results (average for 5 runs) on my new PC: </p> <p> shared_mutex_speed_win32_no_patch: Time spent:1910861 nanoseconds </p> <p> shared_mutex_speed_generic_no_patch: Time spent:6831144 nanoseconds </p> <p> shared_mutex_speed_win32_patch: Time spent:1969341 nanoseconds </p> <p> shared_mutex_speed_generic_patch: Time spent:6782312 nanoseconds </p> <p> shared_mutex_speed_generic_patch_no_interruptions (defined BOOST_THREAD_DONT_PROVIDE_INTERRUPTIONS): Time spent:6798547 nanoseconds </p> <p> shared_mutex_speed_win32_patch_no_interruptions (defined BOOST_THREAD_DONT_PROVIDE_INTERRUPTIONS): Time spent:1998582 nanoseconds </p> <p> In generic implementation most of CPU time is spent on boost::mutex::scoped_lock lk(state_change);. Win32 implementation is lock free and it is a reason why this implementation is very fast. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>viboes</dc:creator> <pubDate>Sun, 17 Feb 2013 16:47:45 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/7906#comment:10 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7906#comment:10</guid> <description> <p> I don't know what I can do to improve this situation. I'm working on fixing some of the shared_mutex fixes on win specific implementation. The generic implementation provides more services, e.g. timed operations which are missing on the win specific implementation. Could I close the ticket? </p> </description> <category>Ticket</category> </item> <item> <dc:creator>viboes</dc:creator> <pubDate>Mon, 18 Feb 2013 20:26:40 GMT</pubDate> <title>status changed; resolution set; milestone deleted https://svn.boost.org/trac10/ticket/7906#comment:11 https://svn.boost.org/trac10/ticket/7906#comment:11 <ul> <li><strong>status</strong> <span class="trac-field-old">assigned</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">wontfix</span> </li> <li><strong>milestone</strong> <span class="trac-field-deleted">To Be Determined</span> </li> </ul> Ticket