<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>CTP Quality</title><link>http://blogs.msdn.com/b/pfxteam/archive/2007/11/29/6558557.aspx</link><description>Community Technology Preview (CTP) releases from Microsoft typically provide early looks at the technologies a team is working on. Frequently, CTP quality is nowhere near what folks might expect from Beta releases and the like, and that's ok. The idea</description><dc:language>en-US</dc:language><generator>Telligent Evolution Platform Developer Build (Build: 5.6.50428.7875)</generator><item><title>re: CTP Quality</title><link>http://blogs.msdn.com/b/pfxteam/archive/2007/11/29/6558557.aspx#6696946</link><pubDate>Fri, 07 Dec 2007 23:53:02 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:6696946</guid><dc:creator>Keith Patrick</dc:creator><description>&lt;p&gt;toub: The slowdown was caused in the different method I used for joining the results of my parse, not in the PFX library itself; I was trying to restructure my outer code to work in a parallel manner without explicit locks.&lt;/p&gt;
&lt;p&gt;I've been trying to wrap my head around the issue, and I think the solution lies within ParallelEnumerable.Concat, as it probably has a much more elegant means for preserving order and sharing the result buffer than my brute force methods. I'm still trying to get my head around the paradigm enough to rewrite my logic, but basically what I do is take in an object with a string value, split it via some delimiter, and end up with the same object, but instead of it containing a string value, it has a bunch of children of the same type as itself, but now *they* have the string values (or depending on how many levels the grammar def is, their children have the strings). Catch is each thread is expected to dump its results in a shared collection while preserving order, and that isn't the most thread-friendly thing to do (and also why I want to try using the PLINQ concatenator instead of my brute force attempts)&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=6696946" width="1" height="1"&gt;</description></item><item><title>re: CTP Quality</title><link>http://blogs.msdn.com/b/pfxteam/archive/2007/11/29/6558557.aspx#6695267</link><pubDate>Fri, 07 Dec 2007 20:17:25 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:6695267</guid><dc:creator>Stephen Toub - MSFT</dc:creator><description>&lt;p&gt;Thanks, Keith. &amp;nbsp;Very interesting. &amp;nbsp;If you wanted to put together a small repro code sample that highlights the kinds of bottlenecks you're running into, we'd be happy to look at it. &amp;nbsp;I'm most curious, though, about your 100x slowdown reported with Parallel.For. &amp;nbsp;Are you comparing that Parallel.For implementation to your original sequential implementation or to a sequential implementation that mimicks the same new approach you're taking?&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=6695267" width="1" height="1"&gt;</description></item><item><title>re: CTP Quality</title><link>http://blogs.msdn.com/b/pfxteam/archive/2007/11/29/6558557.aspx#6689086</link><pubDate>Fri, 07 Dec 2007 08:19:09 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:6689086</guid><dc:creator>Keith Patrick</dc:creator><description>&lt;p&gt;On the speed issue, just for kicks I wanted to try converted a generic grammar parser I wrote because a) it's highly recursive with some relatively tightly-written core algorithms, and b) I had already started refactoring it for a threading recompiler I abandoned recently. &lt;/p&gt;
&lt;p&gt;The the plus side, it was super-easy to wrap the central code in a Parallel.For/Each. I tried both ForEach and later For, trying a couple of ways of getting the results into the result collection. I'm not really expecting a performance gain on my single-core setup with preview bits anyway, but it was interesting in terms of the different PFX methods for enumerating. My Parallel.ForEach version ran 10x slower than the original version using a synch-heavy collection scheme, but with the For, where I store my results for each iteration in an array element and then gather them at the end, it was 100x.&lt;/p&gt;
&lt;p&gt;I'm interesting in comparing it with a PLINQ version of my loop, but that's where it gets a bit more complex in my head to integrate the parallel stuff (extension methods and the SQL-ness of it don't feel natural to me). I do expect performance to improve with later CTPs and upon final release, but comparing the different ways within PFX is interesting, as is trying to restructure my code to me more &amp;quot;pure&amp;quot; (in PFX doc parlance)&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=6689086" width="1" height="1"&gt;</description></item><item><title>.Sitecore  &amp;raquo; Blog Archive   &amp;raquo; PLINQ to Sitecore </title><link>http://blogs.msdn.com/b/pfxteam/archive/2007/11/29/6558557.aspx#6643049</link><pubDate>Sun, 02 Dec 2007 21:59:27 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:6643049</guid><dc:creator>.Sitecore  » Blog Archive   » PLINQ to Sitecore </dc:creator><description>&lt;p&gt;PingBack from &lt;a rel="nofollow" target="_new" href="http://sitecore.alexiasoft.nl/2007/12/02/plinq-to-sitecore/"&gt;http://sitecore.alexiasoft.nl/2007/12/02/plinq-to-sitecore/&lt;/a&gt;&lt;/p&gt;
&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=6643049" width="1" height="1"&gt;</description></item><item><title>re: CTP Quality</title><link>http://blogs.msdn.com/b/pfxteam/archive/2007/11/29/6558557.aspx#6635900</link><pubDate>Sun, 02 Dec 2007 01:47:42 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:6635900</guid><dc:creator>Martin</dc:creator><description>&lt;p&gt;Yes thanks you're right. I noticed this myself after better testing.&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=6635900" width="1" height="1"&gt;</description></item><item><title>Martin</title><link>http://blogs.msdn.com/b/pfxteam/archive/2007/11/29/6558557.aspx#6632506</link><pubDate>Sat, 01 Dec 2007 20:11:20 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:6632506</guid><dc:creator>KubuS</dc:creator><description>&lt;p&gt;Matrix of rank 10 is too small. In this case parallel matrix multiplication will give you no gain, rather performance degradation, as you observed.&lt;/p&gt;
&lt;p&gt;Instead of using Paraller.For inside the calculation algorithm, try moving it one scope higher, when you iterate 1000000 times. Or try testing it on a bigger matrix.&lt;/p&gt;
&lt;p&gt;Remember that parralel coumputing/programming is not a cure for everything, you have to know when to use it, and when fallback to sequential algorithms.&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=6632506" width="1" height="1"&gt;</description></item><item><title>re: CTP Quality</title><link>http://blogs.msdn.com/b/pfxteam/archive/2007/11/29/6558557.aspx#6627957</link><pubDate>Sat, 01 Dec 2007 13:34:31 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:6627957</guid><dc:creator>Martin</dc:creator><description>&lt;p&gt;Is it normal, that using Parallel.For is SLOWER than the normal for?&lt;/p&gt;
&lt;p&gt;I made a little test with MatrixMultiplication, and the parallelizized part was more than two times slower. &lt;/p&gt;
&lt;p&gt;That's the code I used:&lt;/p&gt;
&lt;p&gt;using System;&lt;/p&gt;
&lt;p&gt;using System.Collections.Generic;&lt;/p&gt;
&lt;p&gt;using System.Linq;&lt;/p&gt;
&lt;p&gt;using System.Text;&lt;/p&gt;
&lt;p&gt;using System.Threading;&lt;/p&gt;
&lt;p&gt;namespace PLINQ_Test&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;class Program&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;{&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;static void Main(string[] args)&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;double[,] res = new double[10, 10];&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Console.WriteLine(&amp;quot;press a key&amp;quot;);&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Console.ReadKey();&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Console.WriteLine(System.Environment.TickCount);&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;for (int i = 0; i &amp;lt; 1000000; i++)&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;MatrixMult(10, getRandMat(10), getRandMat(10), res);&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Console.WriteLine(System.Environment.TickCount);&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;for (int i = 0; i &amp;lt; 1000000; i++)&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ParMatrixMult(10, getRandMat(10), getRandMat(10), res);&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Console.WriteLine(System.Environment.TickCount);&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Console.WriteLine(&amp;quot;press a key&amp;quot;);&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Console.ReadKey();&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;private static double[,] getRandMat(int p)&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;double[,] res = new double[p, p];&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Random rand = new Random();&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;for (int i = 0; i &amp;lt; p; i++)&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;for (int j = 0; j &amp;lt; p; j++)&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;res[i, j] = (int)(rand.NextDouble() * 1000);&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return res;&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;static void ParMatrixMult(int size, double[,] m1, double[,] m2, double[,] result)&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Parallel.For(0, size, delegate(int i)&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;for (int j = 0; j &amp;lt; size; j++)&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;result[i, j] = 0;&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;for (int k = 0; k &amp;lt; size; k++)&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;result[i, j] += m1[i, k] * m2[k, j];&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;});&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;static void MatrixMult(int size, double[,] m1, double[,] m2, double[,] result)&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;for(int i=0;i&amp;lt;size;i++) //Parallel.For(0, size, delegate(int i)&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;for (int j = 0; j &amp;lt; size; j++)&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;result[i, j] = 0;&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;for (int k = 0; k &amp;lt; size; k++)&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;result[i, j] += m1[i, k] * m2[k, j];&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=6627957" width="1" height="1"&gt;</description></item></channel></rss>