<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	>
<channel>
	<title>Comments on: 10 Ways to Reduce Lock Contention in Threaded Programs</title>
	<atom:link href="http://www.thinkingparallel.com/2007/07/31/10-ways-to-reduce-lock-contention-in-threaded-programs/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.thinkingparallel.com/2007/07/31/10-ways-to-reduce-lock-contention-in-threaded-programs/</link>
	<description>A Blog on Parallel Programming and Concurrency by Michael Suess</description>
	<pubDate>Sat, 04 Feb 2012 06:31:15 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7</generator>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<item>
		<title>By: Matan</title>
		<link>http://www.thinkingparallel.com/2007/07/31/10-ways-to-reduce-lock-contention-in-threaded-programs/comment-page-1/#comment-98858</link>
		<dc:creator>Matan</dc:creator>
		<pubDate>Thu, 03 Nov 2011 10:57:47 +0000</pubDate>
		<guid isPermaLink="false">http://www.thinkingparallel.com/2007/07/31/10-ways-to-reduce-lock-contention-in-threaded-programs/#comment-98858</guid>
		<description>Just stumbled across this article, better late than never :)
While I'm mostly aware of your points and had the (mis)fortune to do a lot of concurrent programming, I have to say this is an excellent list!

Let me pitch in with 2 comments regarding read-write locks:

1) When using them, find out if and how do the locking functions you're using handle starvation. For example, say you have 3 threads on 3 cpus (one on each). Threads 1 and 2 pretty much do their entire work under the lock in read mode (they release it between tasks but are constantly doing tasks). The 3rd thread runs very rarely but when it does it needs the lock in write mode. Now, imagine an implementation where access is always granted when possible (e.g. Linux 2.6 kernel rwlock_t locks). So, thread 1 obtains the lock for read and do a task. Now thread 3 wants the lock for write so it waits. Midway through thread's 1 work, thread 2 obtains the lock for read. Now thread 1 finishes its task and release the (read) lock but thread 2 still hold it (for read) so thread 3 can't get it (for write). Now, while thread 2 is in the middle of its task, thread 1 starts another task and takes the lock for read. And you can see where I'm going with this. Thread 3 is starved "forever".

2) Assuming you're familiar with the need to define a hierarchy between different locks, read-write locks present some extra difficulty (they actually do that even if you're unfamiliar with locking hierarchy). Suppose you hold a read lock on a data structure, do some work and now decide you need to change the data structure which requires the lock in write mode. Can you change the read lock you have to write mode? You can, but you have to first release the lock for read and then obtain it for write to prevent hierarchy issues (at least in some implementation - otherwise two readers trying to change to write will get into deadlock). What's the added complication here? Between the point were you released the read lock and the point where you obtained the write lock another thread could have modified the database and whatever you've decided to do while holding the read lock and for which you obtained the write lock might not be relevant anymore (which is a nice way to say that your code can crash). Thus, you may need to re-verify some assumptions after you obtain the lock for write.</description>
		<content:encoded><![CDATA[<p>Just stumbled across this article, better late than never <img src='http://www.thinkingparallel.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
While I&#8217;m mostly aware of your points and had the (mis)fortune to do a lot of concurrent programming, I have to say this is an excellent list!</p>
<p>Let me pitch in with 2 comments regarding read-write locks:</p>
<p>1) When using them, find out if and how do the locking functions you&#8217;re using handle starvation. For example, say you have 3 threads on 3 cpus (one on each). Threads 1 and 2 pretty much do their entire work under the lock in read mode (they release it between tasks but are constantly doing tasks). The 3rd thread runs very rarely but when it does it needs the lock in write mode. Now, imagine an implementation where access is always granted when possible (e.g. Linux 2.6 kernel rwlock_t locks). So, thread 1 obtains the lock for read and do a task. Now thread 3 wants the lock for write so it waits. Midway through thread&#8217;s 1 work, thread 2 obtains the lock for read. Now thread 1 finishes its task and release the (read) lock but thread 2 still hold it (for read) so thread 3 can&#8217;t get it (for write). Now, while thread 2 is in the middle of its task, thread 1 starts another task and takes the lock for read. And you can see where I&#8217;m going with this. Thread 3 is starved &#8220;forever&#8221;.</p>
<p>2) Assuming you&#8217;re familiar with the need to define a hierarchy between different locks, read-write locks present some extra difficulty (they actually do that even if you&#8217;re unfamiliar with locking hierarchy). Suppose you hold a read lock on a data structure, do some work and now decide you need to change the data structure which requires the lock in write mode. Can you change the read lock you have to write mode? You can, but you have to first release the lock for read and then obtain it for write to prevent hierarchy issues (at least in some implementation - otherwise two readers trying to change to write will get into deadlock). What&#8217;s the added complication here? Between the point were you released the read lock and the point where you obtained the write lock another thread could have modified the database and whatever you&#8217;ve decided to do while holding the read lock and for which you obtained the write lock might not be relevant anymore (which is a nice way to say that your code can crash). Thus, you may need to re-verify some assumptions after you obtain the lock for write.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Are you trying to reduce your lock contention? - LA.NET [EN]</title>
		<link>http://www.thinkingparallel.com/2007/07/31/10-ways-to-reduce-lock-contention-in-threaded-programs/comment-page-1/#comment-39289</link>
		<dc:creator>Are you trying to reduce your lock contention? - LA.NET [EN]</dc:creator>
		<pubDate>Mon, 07 Jan 2008 23:48:36 +0000</pubDate>
		<guid isPermaLink="false">http://www.thinkingparallel.com/2007/07/31/10-ways-to-reduce-lock-contention-in-threaded-programs/#comment-39289</guid>
		<description>[...] Suess has a great blog on parallel programming and concurrency. Even though this post has already got some months, I still recommend it to everyone that wants to improve their knowledge [...]</description>
		<content:encoded><![CDATA[<p>[...] Suess has a great blog on parallel programming and concurrency. Even though this post has already got some months, I still recommend it to everyone that wants to improve their knowledge [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Legendary Diplomacy &#187; Blog Archive &#187; Scarlet news&#8230;</title>
		<link>http://www.thinkingparallel.com/2007/07/31/10-ways-to-reduce-lock-contention-in-threaded-programs/comment-page-1/#comment-34736</link>
		<dc:creator>Legendary Diplomacy &#187; Blog Archive &#187; Scarlet news&#8230;</dc:creator>
		<pubDate>Thu, 06 Dec 2007 12:02:04 +0000</pubDate>
		<guid isPermaLink="false">http://www.thinkingparallel.com/2007/07/31/10-ways-to-reduce-lock-contention-in-threaded-programs/#comment-34736</guid>
		<description>[...] synchronized home-grown caches forced us to write a common cache adapter on top of them, using a lock-striping solution and than TC-ize that. Not exactly the kind of stuff you code in the [...]</description>
		<content:encoded><![CDATA[<p>[...] synchronized home-grown caches forced us to write a common cache adapter on top of them, using a lock-striping solution and than TC-ize that. Not exactly the kind of stuff you code in the [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Michael Suess</title>
		<link>http://www.thinkingparallel.com/2007/07/31/10-ways-to-reduce-lock-contention-in-threaded-programs/comment-page-1/#comment-18707</link>
		<dc:creator>Michael Suess</dc:creator>
		<pubDate>Fri, 03 Aug 2007 19:48:02 +0000</pubDate>
		<guid isPermaLink="false">http://www.thinkingparallel.com/2007/07/31/10-ways-to-reduce-lock-contention-in-threaded-programs/#comment-18707</guid>
		<description>@Paul: I fully agree, every decisions has its tradeoffs and when in doubt, only your profiler can tell for sure whats better.

@Saurabh: Who says that the list is protected by a lock anyways?  :smile:</description>
		<content:encoded><![CDATA[<p>@Paul: I fully agree, every decisions has its tradeoffs and when in doubt, only your profiler can tell for sure whats better.</p>
<p>@Saurabh: Who says that the list is protected by a lock anyways?  <img src='http://www.thinkingparallel.com/wp-includes/images/smilies/icon_smile.gif' alt=':smile:' class='wp-smiley' /> </p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Saurabh</title>
		<link>http://www.thinkingparallel.com/2007/07/31/10-ways-to-reduce-lock-contention-in-threaded-programs/comment-page-1/#comment-18616</link>
		<dc:creator>Saurabh</dc:creator>
		<pubDate>Thu, 02 Aug 2007 22:59:32 +0000</pubDate>
		<guid isPermaLink="false">http://www.thinkingparallel.com/2007/07/31/10-ways-to-reduce-lock-contention-in-threaded-programs/#comment-18616</guid>
		<description>Nice one, but I dont like your example in item 10 for two reasons:
1. If the append/remove of a link is going to be locked, how much harm can there be in slipping counter in/de-crement inside the lock? I would say that surely wont follow the 80-20 rule and in almost all realistic usage cases it'd be better to store the size inside the list.
2. Item 4 already talks about atomic operations for counters.

Also similar to the object pooling in item 8 is reference counting.</description>
		<content:encoded><![CDATA[<p>Nice one, but I dont like your example in item 10 for two reasons:<br />
1. If the append/remove of a link is going to be locked, how much harm can there be in slipping counter in/de-crement inside the lock? I would say that surely wont follow the 80-20 rule and in almost all realistic usage cases it&#8217;d be better to store the size inside the list.<br />
2. Item 4 already talks about atomic operations for counters.</p>
<p>Also similar to the object pooling in item 8 is reference counting.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Carlo Vella&#8217;s Bits and Bytes &#187; 10 Ways to reduce lock contention in threaded programs</title>
		<link>http://www.thinkingparallel.com/2007/07/31/10-ways-to-reduce-lock-contention-in-threaded-programs/comment-page-1/#comment-18529</link>
		<dc:creator>Carlo Vella&#8217;s Bits and Bytes &#187; 10 Ways to reduce lock contention in threaded programs</dc:creator>
		<pubDate>Wed, 01 Aug 2007 20:59:15 +0000</pubDate>
		<guid isPermaLink="false">http://www.thinkingparallel.com/2007/07/31/10-ways-to-reduce-lock-contention-in-threaded-programs/#comment-18529</guid>
		<description>[...] locks kill scalability and make threaded programs slow. Here are 10 techniques to reduce lock contention&#8230; Bookmark [...]</description>
		<content:encoded><![CDATA[<p>[...] locks kill scalability and make threaded programs slow. Here are 10 techniques to reduce lock contention&#8230; Bookmark [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Paul Betts</title>
		<link>http://www.thinkingparallel.com/2007/07/31/10-ways-to-reduce-lock-contention-in-threaded-programs/comment-page-1/#comment-18526</link>
		<dc:creator>Paul Betts</dc:creator>
		<pubDate>Wed, 01 Aug 2007 19:54:11 +0000</pubDate>
		<guid isPermaLink="false">http://www.thinkingparallel.com/2007/07/31/10-ways-to-reduce-lock-contention-in-threaded-programs/#comment-18526</guid>
		<description>Great article, I didn't think of using the mod operator to protect an array like that, so you have n/k locks instead of n. 

Of course, like every other dev, I've got an opinion to put in about the article - while RW locks seem like a good idea to implement in any scenario that fits conceptually, you should remember that a RW lock typically uses 2 locks and you have to wait on people more, so they could be costing you more than just using a simple lock. However, if you've got a resource that has a *lot* of readers and only occasional writers, it's a win. 

But how much is a lot? Don't guess, profile! There's far too many factors to accurately guess which one to use.</description>
		<content:encoded><![CDATA[<p>Great article, I didn&#8217;t think of using the mod operator to protect an array like that, so you have n/k locks instead of n. </p>
<p>Of course, like every other dev, I&#8217;ve got an opinion to put in about the article - while RW locks seem like a good idea to implement in any scenario that fits conceptually, you should remember that a RW lock typically uses 2 locks and you have to wait on people more, so they could be costing you more than just using a simple lock. However, if you&#8217;ve got a resource that has a *lot* of readers and only occasional writers, it&#8217;s a win. </p>
<p>But how much is a lot? Don&#8217;t guess, profile! There&#8217;s far too many factors to accurately guess which one to use.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Kyle</title>
		<link>http://www.thinkingparallel.com/2007/07/31/10-ways-to-reduce-lock-contention-in-threaded-programs/comment-page-1/#comment-18507</link>
		<dc:creator>Kyle</dc:creator>
		<pubDate>Wed, 01 Aug 2007 16:32:20 +0000</pubDate>
		<guid isPermaLink="false">http://www.thinkingparallel.com/2007/07/31/10-ways-to-reduce-lock-contention-in-threaded-programs/#comment-18507</guid>
		<description>Haskell (GHC, specifically) comes standard with a transactional memory library (STM), with all sorts of bells and whistles (orElse, etc) and it is as production ready as anything else in Haskell.

For reference, see SPJ's OSCon talk or http://haskell.org/ghc/docs/latest/html/libraries/stm/Control-Monad-STM.html</description>
		<content:encoded><![CDATA[<p>Haskell (GHC, specifically) comes standard with a transactional memory library (STM), with all sorts of bells and whistles (orElse, etc) and it is as production ready as anything else in Haskell.</p>
<p>For reference, see SPJ&#8217;s OSCon talk or <a href="http://haskell.org/ghc/docs/latest/html/libraries/stm/Control-Monad-STM.html" rel="nofollow">http://haskell.org/ghc/docs/latest/html/libraries/stm/Control-Monad-STM.html</a></p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Michael Suess</title>
		<link>http://www.thinkingparallel.com/2007/07/31/10-ways-to-reduce-lock-contention-in-threaded-programs/comment-page-1/#comment-18500</link>
		<dc:creator>Michael Suess</dc:creator>
		<pubDate>Wed, 01 Aug 2007 15:14:16 +0000</pubDate>
		<guid isPermaLink="false">http://www.thinkingparallel.com/2007/07/31/10-ways-to-reduce-lock-contention-in-threaded-programs/#comment-18500</guid>
		<description>@Kent: you are right, this is a valid technique for some cases as well, although partly covered by point no. 1 already.&lt;br/&gt;&lt;br/&gt;

@Revence: I am not going to get myself into a language war with you, thats for sure :-).&lt;br/&gt;&lt;br/&gt;

@Brian: thanks for your insightful comment (and for the book, for that matter :-) ), you are right, a warning about the applicability of the techniques is in order. I have added it in big bold letters. Must not forget that people don't read all of my articles, but merely some of them so I need to repeat myself frequently (for example, I have a whole post warning about &lt;a href="http://www.thinkingparallel.com/2006/08/07/my-views-on-high-level-optimization/" rel="nofollow"&gt;premature optimization&lt;/a&gt;).</description>
		<content:encoded><![CDATA[<p>@Kent: you are right, this is a valid technique for some cases as well, although partly covered by point no. 1 already.</p>
<p>@Revence: I am not going to get myself into a language war with you, thats for sure :-).</p>
<p>@Brian: thanks for your insightful comment (and for the book, for that matter <img src='http://www.thinkingparallel.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> ), you are right, a warning about the applicability of the techniques is in order. I have added it in big bold letters. Must not forget that people don&#8217;t read all of my articles, but merely some of them so I need to repeat myself frequently (for example, I have a whole post warning about <a href="http://www.thinkingparallel.com/2006/08/07/my-views-on-high-level-optimization/" rel="nofollow">premature optimization</a>).</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Brian Goetz</title>
		<link>http://www.thinkingparallel.com/2007/07/31/10-ways-to-reduce-lock-contention-in-threaded-programs/comment-page-1/#comment-18498</link>
		<dc:creator>Brian Goetz</dc:creator>
		<pubDate>Wed, 01 Aug 2007 14:39:31 +0000</pubDate>
		<guid isPermaLink="false">http://www.thinkingparallel.com/2007/07/31/10-ways-to-reduce-lock-contention-in-threaded-programs/#comment-18498</guid>
		<description>Nice list.  Just one caveat...&lt;br/&gt;&lt;br/&gt;

These are all good recommendations -- but some of them should be pursued ONLY IF you are experiencing performance or scalability problems.  However, the majority of the time I see some of these techniques in use (lock striping and RW locks especially), they are premature optimization.  I'd prefer to see some disclaimers to that effect, because programmers are drawn to "optimization" like flies to you-know-what. &lt;br/&gt;&lt;br/&gt;

There is a significant trade-off associated with these techniques.  I'll take lock striping as an example, but the reasoning works for RW locks, excessive splitting of synchronized blocks, etc.  Lock striping gives you finer-grained access control, enabling greater concurrency -- but is harder to get right.  With one big fat lock, it's much easier to verify thread safety; with many, its harder.  So this is a tradeoff where you get better potential scalability at the cost of maintainability / fragility. &lt;br/&gt;&lt;br/&gt;

This is sometimes a great trade -- but often is a lousy one.  Do you _know_ that the code in question is the source of performance problems?  If not, you've made your code more complicated, more fragile, and less maintainable for no benefit.  Add this to the fact that most programmers have terrible intuition about where the bottlenecks are.  Without a good measurement program in place, or a deep understanding of the issues (in which case the reader probably doesn't need this advice), most of the time applying these techniques is (at best) premature optimization.  &lt;br/&gt;&lt;br/&gt;

I would rename item #5 "Trust the libraries".</description>
		<content:encoded><![CDATA[<p>Nice list.  Just one caveat&#8230;</p>
<p>These are all good recommendations &#8212; but some of them should be pursued ONLY IF you are experiencing performance or scalability problems.  However, the majority of the time I see some of these techniques in use (lock striping and RW locks especially), they are premature optimization.  I&#8217;d prefer to see some disclaimers to that effect, because programmers are drawn to &#8220;optimization&#8221; like flies to you-know-what. </p>
<p>There is a significant trade-off associated with these techniques.  I&#8217;ll take lock striping as an example, but the reasoning works for RW locks, excessive splitting of synchronized blocks, etc.  Lock striping gives you finer-grained access control, enabling greater concurrency &#8212; but is harder to get right.  With one big fat lock, it&#8217;s much easier to verify thread safety; with many, its harder.  So this is a tradeoff where you get better potential scalability at the cost of maintainability / fragility. </p>
<p>This is sometimes a great trade &#8212; but often is a lousy one.  Do you _know_ that the code in question is the source of performance problems?  If not, you&#8217;ve made your code more complicated, more fragile, and less maintainable for no benefit.  Add this to the fact that most programmers have terrible intuition about where the bottlenecks are.  Without a good measurement program in place, or a deep understanding of the issues (in which case the reader probably doesn&#8217;t need this advice), most of the time applying these techniques is (at best) premature optimization.  </p>
<p>I would rename item #5 &#8220;Trust the libraries&#8221;.</p>
]]></content:encoded>
	</item>
</channel>
</rss>

