{"id":255,"date":"2011-03-08T10:07:07","date_gmt":"2011-03-08T09:07:07","guid":{"rendered":"http:\/\/dev.flauschig.ch\/wordpress\/?p=255"},"modified":"2011-03-10T09:22:35","modified_gmt":"2011-03-10T08:22:35","slug":"xna-4-0-multithreading","status":"publish","type":"post","link":"http:\/\/dev.flauschig.ch\/wordpress\/?p=255","title":{"rendered":".Net \/ XNA 4.0 Multithreading"},"content":{"rendered":"<p>Yesterday, I made my first multithreaded tests with XNA 4.0.<\/p>\n<p>I started with my own <code>WorkerThreadManager<\/code>, a <code>BlockingQueue<\/code> and some <code>WaitHandles<\/code> to setup a Worker-Queue and Workers. The testproject was a an XNA-App just drawing circles and move them around (with collision detection on the walls). The first test was rather disappointing. I could run about 4x more circles in single-threaded mode than with multi-threaded approach.<\/p>\n<p>After some profiling, I found that the <code>BlockingQueue<\/code>was the bottleneck. I then found the class <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/dd267312.aspx\">BlockingCollection<\/a> from .Net 4.0. Using that one improved the speed quite a bit but still about 3x slower than the single-threaded one.<\/p>\n<p>After some more research, I stumbled accross the brand-new <a href=\"http:\/\/msdn.microsoft.com\/de-de\/library\/system.threading.tasks.aspx\">System.Threading.Tasks<\/a> Namespace with some quite interesting classes.<br \/>\nI could replace my whole ThreadManager with this little piece of code:<\/p>\n<pre class=\"brush: csharp; gutter: false; title: ; toolbar: false; wrap-lines: false; notranslate\" title=\"\">\r\nList&lt;Agent&gt; agentList = SomeHowGetSomeAgents();\r\nTask&#x5B;] tasks = new Task&#x5B;agentList.Count];\r\nfor (int index = 0; index &lt; agentList.Count; index++)\r\n{\r\n    Agent agent = agentList&#x5B;index];\r\n    Task t = Task.Factory.StartNew(() =&gt; DoSomeWork(agent));\r\n    tasks&#x5B;index] = t;\r\n}\r\nTask.WaitAll(tasks);\r\n<\/pre>\n<p>Nice, eh. That further improved the speed but again, it&#8217;s still about 2x slower than the single-threaded one&#8230;<\/p>\n<p>So I found one more class called <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.threading.tasks.parallel.aspx\">Parallel<\/a>.<br \/>\nWith this class, the code now looks like:<\/p>\n<pre class=\"brush: csharp; gutter: false; title: ; toolbar: false; wrap-lines: false; notranslate\" title=\"\">\r\nList&lt;Agent&gt; agentList = SomeHowGetSomeAgents();\r\nParallel.ForEach(agentList, DoSomeWork);\r\n<\/pre>\n<p>That one finally runs faster than the single-threaded approach. Three times faster!<\/p>\n<p>I might need to redo all those tests when the <code>DoSomeWork<\/code> is much more sophisticated. But for now, <code>Parallel<\/code> seems the way to go for simple Worker-Threads.<\/p>\n<p>More on this Topic:<\/p>\n<ul>\n<li><a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/dd460693.aspx\">Parallel Programming in the .NET Framework<\/a><\/li>\n<li><a href=\"http:\/\/blogs.msdn.com\/b\/pfxteam\/\">Parallel Programming in the .NET Framework (Blog)<\/a><\/li>\n<li><a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/dd287108.aspx\">System.Collections.Concurrent Namespace<\/a><\/li>\n<li><a href=\"http:\/\/www.albahari.com\/threading\/part5.aspx\">Threading in C# &#8211; Parallel Programming<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Yesterday, I made my first multithreaded tests with XNA 4.0. I started with my own WorkerThreadManager, a BlockingQueue and some WaitHandles to setup a Worker-Queue and Workers. The testproject was a an XNA-App just drawing circles and move them around (with collision detection on the walls). The first test was rather disappointing. I could run &hellip; <\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[4,107],"tags":[109,108,148],"class_list":{"0":"entry","1":"post","2":"publish","3":"author-roemer","4":"post-255","6":"format-standard","7":"category-csharp","8":"category-xna","9":"post_tag-4-0","10":"post_tag-multithreading","11":"post_tag-xna"},"acf":[],"views":5317,"_links":{"self":[{"href":"http:\/\/dev.flauschig.ch\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/255"}],"collection":[{"href":"http:\/\/dev.flauschig.ch\/wordpress\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/dev.flauschig.ch\/wordpress\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/dev.flauschig.ch\/wordpress\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/dev.flauschig.ch\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=255"}],"version-history":[{"count":0,"href":"http:\/\/dev.flauschig.ch\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/255\/revisions"}],"wp:attachment":[{"href":"http:\/\/dev.flauschig.ch\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=255"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/dev.flauschig.ch\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=255"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/dev.flauschig.ch\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=255"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}