<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>JIT, NGen, and other Managed Code Generation Stuff</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/clrcodegeneration/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/clrcodegeneration/feed.xml</link>
    <description>Details about RyuJIT stuff of all sort...</description>
    <lastBuildDate>Tue, 16 Apr 2019 04:55:46 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>RyuJIT tutorial at CGO and PLDI conferences</title>
      <link>https://docs.microsoft.com/archive/blogs/clrcodegeneration/ryujit-tutorial-at-cgo-and-pldi-conferences</link>
      <pubDate>Tue, 02 Feb 2016 15:15:00 GMT</pubDate>
      <dc:creator><![CDATA[Bruce Forstall]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/clrcodegeneration/2016/02/02/ryujit-tutorial-at-cgo-and-pldi-conferences/</guid>
      <description><![CDATA[For those of you interested in learning more about the internals of RyuJIT, Carol Eidt will be...]]></description>
      <content:encoded><![CDATA[<p>For those of you interested in learning more about the internals of RyuJIT, <a href="https://github.com/CarolEidt">Carol Eidt</a> will be giving a <a href="https://cgo.org/cgo2016/event/ryujit-the-open-source-jit-for-net-ryujit/?instance_id=16">tutorial</a>&nbsp;at <a href="https://cgo.org/cgo2016/">CGO</a> in Barcelona on March 13. She will also be giving the tutorial at <a href="https://conf.researchr.org/home/pldi-2016">PLDI</a> in Santa Barbara, CA in June. She&rsquo;ll describe the internal representation and compilation phases, and then walk through the process of adding a simple feature.</p>
<p>The early registration deadline for CGO is tomorrow, February 3, so if you are interested in attending, now&rsquo;s the time to act.</p>
<p>&nbsp;</p>]]></content:encoded>
    </item>
    <item>
      <title>Announcing the release of RyuJIT for x64!</title>
      <link>https://docs.microsoft.com/archive/blogs/clrcodegeneration/announcing-the-release-of-ryujit-for-x64</link>
      <pubDate>Mon, 20 Jul 2015 16:13:00 GMT</pubDate>
      <dc:creator><![CDATA[Bruce Forstall]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/clrcodegeneration/2015/07/20/announcing-the-release-of-ryujit-for-x64/</guid>
      <description><![CDATA[After many years of work, RyuJIT for x64 has now been released! Thanks to many of you trying it out...]]></description>
      <content:encoded><![CDATA[<p>After many years of work, RyuJIT for x64 has now been released! Thanks to many of you trying it out over the course of the last couple years via our CTP releases, and giving us valuable feedback.</p>
<p>You can read all about the .NET Framework 4.6 release (which includes RyuJIT)&nbsp;here: <a href="https://blogs.msdn.com/b/dotnet/archive/2015/07/20/announcing-net-framework-4-6.aspx">https://blogs.msdn.com/b/dotnet/archive/2015/07/20/announcing-net-framework-4-6.aspx</a>.</p>
<p>You can see Soma's blog post on the Visual Studio 2015 and .NET Framework 4.6 releases here: <a href="https://blogs.msdn.com/b/somasegar/archive/2015/07/20/visual-studio-2015-and-net-4-6-available-for-download.aspx">https://blogs.msdn.com/b/somasegar/archive/2015/07/20/visual-studio-2015-and-net-4-6-available-for-download.aspx</a>.</p>
<p>Enjoy these releases, and keep the feedback coming!</p>
<p>&nbsp;</p>]]></content:encoded>
    </item>
    <item>
      <title>RyuJIT and .NET 4.6</title>
      <link>https://docs.microsoft.com/archive/blogs/clrcodegeneration/ryujit-and-net-4-6</link>
      <pubDate>Wed, 27 May 2015 14:14:00 GMT</pubDate>
      <dc:creator><![CDATA[Bruce Forstall]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/clrcodegeneration/2015/05/27/ryujit-and-net-4-6/</guid>
      <description><![CDATA[It&rsquo;s been a while since we&rsquo;ve posted here, and a lot has happened with RyuJIT since the...]]></description>
      <content:encoded><![CDATA[<p>It&rsquo;s been a while since we&rsquo;ve posted here, and a lot has happened with RyuJIT since the last post.</p>
<p>First and foremost, RyuJIT is the default x64 JIT for .NET 4.6! As a result, there is no need to use a RyuJIT CTP to try out RyuJIT. If you install the .NET 4.6 Preview (included in Visual Studio 2015 Preview), or later build, such as Visual Studio 2015 RC, you will be using it. See <a title="here" href="https://blogs.msdn.com/b/somasegar/archive/2015/04/29/introducing-visual-studio-code-visual-studio-2015-rc-application-insights-public-preview-and-net-core-for-linux-and-mac.aspx">here</a>&nbsp;or the <a title=".NET blog" href="https://blogs.msdn.com/b/dotnet/">.NET blog</a> for more details.</p>
<p>One thing we need to point out, though: if you have previously configured your machine to use a RyuJIT CTP (using the instruction <a title="here" href="https://blogs.msdn.com/b/dotnet/archive/2013/09/30/ryujit-the-next-generation-jit-compiler.aspx">here</a>), and you update to .NET 4.6, <em>you need to make sure the COMPLUS_AltJit environment variable and the HKLM\SOFTWARE\Microsoft\.NETFramework\AltJit registry value do not exist</em>. If they do exist, every .NET application will fail to run. You don&rsquo;t want that!</p>
<p><strong>Update</strong>: the specific failure you will get is exception number -2146233082 (in hex: 0x80131506), otherwise known as COR_E_EXECUTIONENGINE or "Internal CLR error". This will be the process exit code. For console applications, you can see this by examining %ERRORLEVEL% after the process terminates (if you are working in a CMD.EXE window). You may also see a dialog box stating "&lt;application&gt; has stopped working", and if you expand "View problem details", you will see "Fault Module Name: clr.dll" and "Exception Code: 80131506". You will also see an entry in the Event Viewer, Application log, source ".NET Runtime", listing this error code. Note that there are other reasons this exception number could be generated; a stray AltJit configuration is not the only reason for this exception.</p>
<p>Note that this information has also been published as KB3065367 <a title="here" href="https://support.microsoft.com/en-us/kb/3065367">here</a>.</p>
<p>Secondly, RyuJIT is now open source! See <a title="here" href="https://blogs.msdn.com/b/dotnet/archive/2015/02/03/coreclr-is-now-open-source.aspx">here</a> for details.&nbsp;</p>
<p>We hope you enjoy the benefits of all the work we&rsquo;ve put into RyuJIT. If you have any feedback on RyuJIT, send us mail at <a href="mailto:ryujit@microsoft.com">ryujit@microsoft.com</a>. We want to hear from you!</p>
<p>&nbsp;</p>]]></content:encoded>
    </item>
    <item>
      <title>RyuJIT CTP5: Getting closer to shipping, and with better SIMD support</title>
      <link>https://docs.microsoft.com/archive/blogs/clrcodegeneration/ryujit-ctp5-getting-closer-to-shipping-and-with-better-simd-support</link>
      <pubDate>Thu, 30 Oct 2014 17:12:00 GMT</pubDate>
      <dc:creator><![CDATA[Thomas Lai]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/clrcodegeneration/2014/10/30/ryujit-ctp5-getting-closer-to-shipping-and-with-better-simd-support/</guid>
      <description><![CDATA[Hi Folks!&nbsp; Yes, we understand it&rsquo;s been a while since we shipped the last RyuJIT...]]></description>
      <content:encoded><![CDATA[<p>Hi Folks!&nbsp; Yes, we understand it&rsquo;s been a while since we shipped the last RyuJIT CTP.&nbsp; We have been working hard on improving our SIMD support and getting RyuJIT to ship quality for the next version of the .NET Framework.&nbsp; So without further ado, here&rsquo;s a quick description of what you can expect from <a title="RyuJIT CTP5" href="https://aka.ms/RyuJIT" target="_blank">RyuJIT CTP5</a>.</p>
<p>&nbsp;</p>
<p><strong>Correctness</strong></p>
<p>We have spent a lot of time finding and fixing those last few pesky corner-case functional issues in RyuJIT.&nbsp; Fortunately, we have the luxury of having many internal partners with a significant managed codebase, making it easy to throw as much managed code as we can find at RyuJIT.&nbsp; While some of the issues we have found are legitimate bugs, others are not so clear cut.&nbsp; For example, we have found that JIT64 accommodates some illegal IL disallowed by the ECMA spec.&nbsp; Since backward compatibility is a major concern for us, we evaluate these issues on a case-by-case basis to decide if we should quirk RyuJIT to accommodate the same illegal IL.</p>
<p>&nbsp;</p>
<p><strong>Real-World Throughput Wins</strong></p>
<p>In case you have missed the <a title="original blog post" href="https://blogs.msdn.com/b/dotnet/archive/2013/09/30/ryujit-the-next-generation-jit-compiler.aspx" target="_blank">original blog post</a> announcing the first CTP, RyuJIT beats JIT64 handily in terms of throughput while staying very competitive in terms of code quality (CQ).&nbsp; Recently the Bing team has tried using RyuJIT on top of 4.5.1 in some of their processing, and they see a 25% reduction in startup time in their scenario.&nbsp; This is the most significant real-world throughput win we have witnessed on RyuJIT thus far.&nbsp; :)</p>
<p>&nbsp;</p>
<p><strong>Code Quality</strong></p>
<p>We didn&rsquo;t publish any benchmark results with RyuJIT CTP4, so here are some graphs to show that we haven&rsquo;t regressed CQ in RyuJIT CTP5.&nbsp; However, since CQ hasn&rsquo;t been the focus for this CTP, we also haven&rsquo;t made any significant improvements either.</p>
<p>These graphs follow the same basic format as previous ones.&nbsp; The higher the bar, the better RyuJIT CTP5 is at that benchmark.&nbsp; The grey area is the standard deviation, so any benchmark falling in the grey area is just noise.&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/89/26/3201.Graph%20-%20RyuJIT%20CTP5%20vs.%20JIT64.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-89-26/3201.Graph-_2D00_-RyuJIT-CTP5-vs.-JIT64.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/89/26/3201.Graph%20-%20RyuJIT%20CTP5%20vs.%20JIT64.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-89-26/3201.Graph-_2D00_-RyuJIT-CTP5-vs.-JIT64.png" alt="" border="0" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/89/26/2376.Graph%20-%20RyuJIT%20CTP5%20vs.%20RyuJIT%20CPT4.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-89-26/2376.Graph-_2D00_-RyuJIT-CTP5-vs.-RyuJIT-CPT4.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/89/26/2376.Graph%20-%20RyuJIT%20CTP5%20vs.%20RyuJIT%20CPT4.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-89-26/2376.Graph-_2D00_-RyuJIT-CTP5-vs.-RyuJIT-CPT4.png" alt="" border="0" /></a></p>
<p>&nbsp;<strong>&nbsp;</strong></p>
<p><strong>What&rsquo;s New in JIT Support for SIMD types?</strong></p>
<p>RyuJIT CTP5 supports acceleration of the latest version of the Vector APIs available via NuGet <a title="here" href="https://www.nuget.org/packages/Microsoft.Bcl.Simd" target="_blank">here</a>.&nbsp; This version contains a number of changes that were requested by developers.</p>
<p>One of the most popular requests was to publicly expose the fields of the fixed-size vector types (e.g. Vector2.X).&nbsp; Why wasn&rsquo;t this done originally?&nbsp; The short answer is that it was for performance, but really it was to make it easier for the JIT to handle all the references to these types as intrinsics, and to transform them into the appropriate target instructions.&nbsp; It&rsquo;s a tricky business, however, to determine where to allocate a local Vector instance for best efficiency:</p>
<ul>
<li>If the instance will be primarily used in Vector intrinsics, putting it in an xmm/ymm register is the best option.</li>
<li>If the instance will primarily be referenced via its fields, then either putting it in memory, or separately allocating its fields to registers, is the best option.</li>
<li>If the instance is larger than 8 bytes (i.e. not a Vector2), and it is primarily passed as a method argument, then putting it in memory is the best option.</li>
</ul>
<p>With CTP5 we have made the JIT a bit smarter about identifying these field accesses, analyzing the usage of the vector instance, and selecting among these options, but there is still room for improvement, so you may find that some SIMD code runs more slowly with this new release.</p>
<p>We&rsquo;ve also improved register allocation for SIMD types, reducing a number of cases where we had unnecessary copies of vector registers.</p>
<p>Since we are talking about SIMD performance, it wouldn&rsquo;t be fair to not include any SIMD benchmark results.&nbsp; We are using the sample code <a title="here" href="https://code.msdn.microsoft.com/SIMD-Sample-f2c8c35a" target="_blank">here</a> as our SIMD benchmarks.&nbsp; (However, note that we are using an updated version of RayTracer which uses our latest Vector APIs.&nbsp; We&rsquo;ll update the sample shortly.)</p>
<p>&nbsp;</p>
<p>&nbsp;<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/89/26/5141.Graph%20-%20Vector%20Mandelbrot%20on%20RyuJIT%20CTP5.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-89-26/5141.Graph-_2D00_-Vector-Mandelbrot-on-RyuJIT-CTP5.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/89/26/5141.Graph%20-%20Vector%20Mandelbrot%20on%20RyuJIT%20CTP5.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-89-26/5141.Graph-_2D00_-Vector-Mandelbrot-on-RyuJIT-CTP5.png" alt="" border="0" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/89/26/0552.Graph%20-%20RayTracer%20on%20RyuJIT%20CTP5.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-89-26/0552.Graph-_2D00_-RayTracer-on-RyuJIT-CTP5.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/89/26/0552.Graph%20-%20RayTracer%20on%20RyuJIT%20CTP5.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-89-26/0552.Graph-_2D00_-RayTracer-on-RyuJIT-CTP5.png" alt="" border="0" /></a></p>
<p>&nbsp;</p>
<p>Stay tuned &ndash; we are continuing to work on performance for SIMD types, including tuning of inlining heuristics for SIMD methods, and improved dead store elimination.&nbsp; We&rsquo;ll also be diving into the usage data from Bing and other internal partners to see how we can improve the performance of RyuJIT even more on both throughput and CQ.</p>
<p>In case you need them again, you can refer to this <a title="blog post" href="https://blogs.msdn.com/b/dotnet/archive/2013/09/30/ryujit-the-next-generation-jit-compiler.aspx" target="_blank">blog post</a> for the instructions to turn on RyuJIT, and this <a title="blog post" href="https://blogs.msdn.com/b/clrcodegeneration/archive/2014/04/03/ryujit-ctp3-how-to-use-simd.aspx" target="_blank">blog post</a> for instructions on using SIMD.&nbsp; Note that if you are running on the <a title="4.5.2" href="https://go.microsoft.com/fwlink/?LinkId=397674" target="_blank">4.5.2</a> version of the .NET Framework, you can use RyuJIT CTP5 on Windows Vista, 7, 8, and 8.1&nbsp;as well as&nbsp;Windows Server 2008,&nbsp;2008&nbsp;R2, 2012, and&nbsp;2012 R2.&nbsp; However, RyuJIT CTP5 currently doesn't work on <a title="Visual Studio &quot;14&quot; CTP4" href="https://www.visualstudio.com/en-us/downloads/visual-studio-14-ctp-vs.aspx" target="_blank">Visual Studio "14" CTP4</a>.&nbsp; You don't need it anyway, since RyuJIT is enabled by default on Visual Studio "14" CTP4.&nbsp; :)&nbsp; (The version of RyuJIT in Visual Studio "14" CTP4 is slightly older than this CTP, but not by much.)</p>]]></content:encoded>
    </item>
    <item>
      <title>RyuJIT CTP4: Now with more SIMD types, and better OS support!</title>
      <link>https://docs.microsoft.com/archive/blogs/clrcodegeneration/ryujit-ctp4-now-with-more-simd-types-and-better-os-support</link>
      <pubDate>Mon, 12 May 2014 10:49:00 GMT</pubDate>
      <dc:creator><![CDATA[Kevin Frei]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/clrcodegeneration/2014/05/12/ryujit-ctp4-now-with-more-simd-types-and-better-os-support/</guid>
      <description><![CDATA[Hi, folks. It&rsquo;s been a busy month around here. We&rsquo;ve been working on all sorts of stuff...]]></description>
      <content:encoded><![CDATA[<p>Hi, folks. It&rsquo;s been a busy month around here. We&rsquo;ve been working on all sorts of stuff that I can&rsquo;t talk about right now, but in the meantime, we&rsquo;ve also been responding to feedback on the SIMD types. So, since it&rsquo;s busy, I&rsquo;m just going to list off the details, and link to other places for more information.</p>
<ol>
<li>Probably the biggest news is that if you install the <a href="https://go.microsoft.com/fwlink/?LinkId=397674" target="_blank">4.5.2</a> runtime (check the <a href="https://blogs.msdn.com/b/dotnet/archive/2014/05/05/announcing-the-net-framework-4-5-2-release.aspx" target="_blank">.NET blog</a> for details on that), you can use<a href="https://aka.ms/RyuJIT"> RyuJIT CTP4</a> on Windows Vista, 7, and 8, as well as Windows Server 2008, 2008 R2, and 2012. In the CTP1 FAQ, I made mention that 4.5.1 on &ldquo;downlevel&rdquo; OS&rsquo;es looked different from a code generation perspective. Well, that&rsquo;s been addressed in the 4.5.2 update, so we&rsquo;re happy to support RyuJIT CTP4 across all platforms that support 4.5.2.</li>
<li>Nearly all the available Vector&lt;T&gt; types are now accelerated! The only ones missing are Vector&lt;uint&gt; and Vector&lt;ulong&gt;. In addition, there are a handful of other methods that we are now accelerating, including the CopyTo() method, which means any performance you have measured is now completely invalidated! Wait, no I mean, any performance you measured could potentially be faster!</li>
<li>The fixed-size vector types are all mutable, now. This was the single biggest piece of feedback we received, so we took it.</li>
</ol>
<p>There you have it. For now, you can download the CTP4 bits from <a href="https://aka.ms/RyuJIT" target="_blank">here</a>. The BCL SIMD NuGet package has also been updated, so update that,&nbsp;and you should be good to go. Same directions as <a href="https://blogs.msdn.com/b/clrcodegeneration/archive/2014/04/03/ryujit-ctp3-how-to-use-simd.aspx" target="_blank">before</a> for how to use the types, enable RyuJIT, all that stuff. As always, send feedback to ryujit@microsoft.com. Happy RyuJIT-ing!</p>
<p>-Kev</p>]]></content:encoded>
    </item>
    <item>
      <title>Quick info about a great SIMD writeup</title>
      <link>https://docs.microsoft.com/archive/blogs/clrcodegeneration/quick-info-about-a-great-simd-writeup</link>
      <pubDate>Thu, 24 Apr 2014 13:24:00 GMT</pubDate>
      <dc:creator><![CDATA[Kevin Frei]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/clrcodegeneration/2014/04/24/quick-info-about-a-great-simd-writeup/</guid>
      <description><![CDATA[Hi, folks. I wanted to put together a more coherent version of a random Twitter conversation I had...]]></description>
      <content:encoded><![CDATA[<p>Hi, folks. I wanted to put together a more coherent version of a random Twitter <a title="converstaion" href="https://twitter.com/goldshtn/status/458622517595615232">conversation</a> I had with Sasha Goldshtein.</p>
<p>First, you should go read Sasha's excellent write-up on SIMD: <a href="https://blogs.microsoft.co.il/sasha/2014/04/22/c-vectorization-microsoft-bcl-simd/">https://blogs.microsoft.co.il/sasha/2014/04/22/c-vectorization-microsoft-bcl-simd/</a>. He's done an excellent job of talking about how scalar &amp; vector operations compare, and really dug in deep to performance of the generated code.</p>
<p>Okay, now let me explain a few things. Sasha's looking at the code quality coming out of the preview: we know this code quality is less than optimal. Here's what I'm seeing from the same code with a compiler I built about 30&nbsp;minutes ago (Siva, one of the JIT devs, just got CopyTo recognized as an intrinsic function):</p>
<pre>; parameters: RCX = a, RDX = b (as before)
    sub    rsp,28h
    xor    eax,eax                          ;rax = i (init to zero)
    mov    r8d,dword ptr [rcx+8]            ;r8d = a.Length
    test   r8d,r8d
    jle    bail_out                         ;r8d &lt;= 0?
    mov    r9d,dword ptr [rdx+8]            ;r9d = b.Length
loop:
    lea    r10d,[rax+3]                     ;r10d = i + 3
    cmp    r10d,r8d                         ;we still have to range check the read from the array of &amp;a[i+3]
    jae    range_check_fail
    mov    r11,rcx
    movupd xmm0,xmmword ptr [r11+rax*4+10h] ;xmm0 = {a[i], a[i+1], a[i+2], a[i+3]}
    cmp    r10d,r9d                         ;and we have to range check b[i+3], too...
    jae    range_check_fail                 ;this one too :-(
    movupd xmm1,xmmword ptr [rdx+rax*4+10h] ;xmm1 = {b[i], b[i+1], b[i+2], b[i+3]}
    addps  xmm0,xmm1                        ;xmm0 += xmm1
    movupd xmmword ptr [r11+rax*4+10h],xmm0 ;{a[i], a[i+1], a[i+2], a[i+3]} = xmm0
    add    eax,4                            ;i += 1 * sizeof(float)
    cmp    r8d,eax                          ;a.Length &gt; i?
    jg     loop
bail_out:
    add    rsp,28h
    ret
range_check_fail:
    call   clr!JIT_RngChkFail (00007ff9`a6d46590)
    int    3</pre>
<p>So the most egregious code quality issue is gone (we're going to try and get an update out quickly: I'm saying mid-May, but things could change :-/). That gives me numbers like this:</p>
<pre>Scalar adding numbers: 765msec</pre>
<pre>SIMD adding numbers: 210msec</pre>
<p>MUCH better. But Sasha makes another interesting point: why did we create two versions of the scalar loop, but left those pesky bounds checks in the SIMD loop? Well, for starters, the two functions aren't identical. The SIMD version will actually throw a bounds check failure exception. To fix that, we actually need to change (some might say "fix" :-)) the code:</p>
<pre class="scroll"><code class="csharp">static void AddPointwiseSimd(float[] a, float[] b)<br />{<br /> int simdLength = Vector&lt;float&gt;.Length;<br /> int i = 0;<br /> for (i = 0; i &lt; a.Length - simdLength; i += simdLength)<br /> {<br /> Vector&lt;float&gt; va = new Vector&lt;float&gt;(a, i);<br /> Vector&lt;float&gt; vb = new Vector&lt;float&gt;(b, i);<br /> va += vb;<br /> va.CopyTo(a, i);<br /> }<br /> for (; i &lt; a.Length; ++i)<br /> {<br /> a[i] += b[i];<br /> }<br />}</code></pre>
<p>And now you might be expecting some great revelation. Nope. Sasha's right: we're missing some fairly straight-forward bound checks here. And we're not dual-versioning the loop, like RyuJIT does for normal scalar loops. Both items are on our to-do list. But the original code Sasha wrote would probably never have those optimizations. Hopefully, we'll get our bounds-check elimination work strengthened enough to make this code truly impressive. Until then, you'll have to limp along with only a 3.6x performance boost.</p>]]></content:encoded>
    </item>
    <item>
      <title>RyuJIT CTP3 minor fix</title>
      <link>https://docs.microsoft.com/archive/blogs/clrcodegeneration/ryujit-ctp3-minor-fix</link>
      <pubDate>Thu, 10 Apr 2014 22:10:37 GMT</pubDate>
      <dc:creator><![CDATA[Kevin Frei]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/clrcodegeneration/2014/04/10/ryujit-ctp3-minor-fix/</guid>
      <description><![CDATA[Hi, folks. I'm on vacation, but I figured I'd let everyone know what the RyuJIT team has been up to...]]></description>
      <content:encoded><![CDATA[<p>Hi, folks. I'm on vacation, but I figured I'd let everyone know what the RyuJIT team has been up to since the beginning of the week. There was a pretty nasty bug that slipped through into CTP3 that I'll let someone else explain in more detail because I'm tired (something about tail-calling delegates). If you have troubles, you should&nbsp;uninstall CTP3, then go hit <a href="https://aka.ms/RyuJIT">https://aka.ms/RyuJIT</a> to download CTP3b, which includes the fix for the <a href="https://twitter.com/jrusbatch/status/452096536416370688">PowerShell Bug</a> that folks reported.</p>
<p>And quickly, no, I'm not normally a work-aholic: I didn't check e-mail once since leaving work last Friday, until&nbsp;I needed the break from my vacation Wednesday after using a 1 man auger to dig 16 holes in my back yard. So having the engineers that actually make the stuff (and fix the bugs) call me and ask me to sign off &amp; whatnot gave my aging back a nice break from hefting around 55&nbsp;lb. pier blocks and 80 lb. sacks of gravel.</p>
<p>-Kev</p>]]></content:encoded>
    </item>
    <item>
      <title>RyuJIT CTP3: How to use SIMD</title>
      <link>https://docs.microsoft.com/archive/blogs/clrcodegeneration/ryujit-ctp3-how-to-use-simd</link>
      <pubDate>Thu, 03 Apr 2014 16:01:00 GMT</pubDate>
      <dc:creator><![CDATA[Kevin Frei]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/clrcodegeneration/2014/04/03/ryujit-ctp3-how-to-use-simd/</guid>
      <description><![CDATA[SIMD details will be forthcoming from the .NET blog, but Soma's already showed some sample code, and...]]></description>
      <content:encoded><![CDATA[<p>SIMD details will be forthcoming from the .NET blog, but Soma's already showed some sample code, and everything's available, so until those details are available here are directions about how to kick the SIMD tires:</p>
<ol>
<li>Go get <a href="https://aka.ms/RyuJIT">RyuJIT CTP3</a> and install it (requires x64 Windows 8.1 or Window Server 2012R2, same as before)</li>
<li>Set the "use RyuJIT" environment variable: <span style="font-family: courier new,courier;">set COMPLUS_AltJit=*</span></li>
<ul>
<li><strong><span style="text-decoration: underline;">Update:</span>&nbsp;make sure you un-set this when you are done testing RyuJIT! See <a title="here" href="https://blogs.msdn.com/b/clrcodegeneration/archive/2015/05/27/ryujit-and-net-4-6.aspx">here</a> for more details.</strong></li>
</ul>
<li>Now pay attention, because things diverge here&nbsp;a bit:</li>
<li>Set a new (and temporary) &ldquo;enable SIMD stuff&rdquo; environment variable: <span style="font-family: courier new,courier;">set COMPLUS_FeatureSIMD=1</span></li>
<li>Add the <span style="font-family: courier new,courier;">Microsoft.Bcl.Simd</span> NuGet package to your project (you must select &ldquo;include Prerelease&rdquo; or use the &ndash;Pre option)</li>
<li>Tricky thing necessary until RyuJIT is final: Add a reference to <span style="font-family: courier new,courier;">Microsoft.Numerics.Vectors.Vector&lt;T&gt;</span> to a class constructor that will be invoked BEFORE your methods that use the new Vector types. I&rsquo;d suggest just putting it in your program&rsquo;s entry class&rsquo;s constructor. It must occur in the class constructor, <strong><em>not</em></strong> the instance constructor.</li>
<li>Make sure your application is actually running on x64. If you don't see protojit.dll loaded in your process (tasklist /M protojit.dll) then you've missed something here.</li>
</ol>
<p>You can&nbsp;take a gander at some sample code sitting over <a href="https://code.msdn.microsoft.com/SIMD-Sample-f2c8c35a">here</a>. It's pretty well commented, at least the VectorFloat.cs file is in the Mandelbrot demo. I spent almost as much time making sure comments were good as writing those 24 slightly different implementations of the Mandelbrot calculation. Take a look at the Microsoft.Numerics.Vectors namespace: there some stuff in Vector&lt;T&gt;, some stuff in VectorMath, and some stuff in plain Vector. And there are also "concrete types" for 2, 3, and 4 element floats.</p>
<p>One quick detail, for those of you that are trying this stuff out immediately: our plan (and we've already prototyped this) is to have Vector&lt;T&gt; automatically use AVX SIMD types on hardware where the performance of AVX code should be better than SSE2. Doing that properly, however,&nbsp;requires some changes to the .NET runtime. We're only able to support SSE2 for the CTP release because of that restriction (and time wasn't really on our side, either).</p>
<p>I&rsquo;ll try to answer questions down below. I know this doesn&rsquo;t have much detail. We&rsquo;ve been <em>really</em> busy trying to get CTP3 out the door (it was published about 45 seconds before Jay&rsquo;s slide went up). Many more details are coming. One final piece of info: SIMD isn&rsquo;t the only thing we&rsquo;ve been doing over the past few weeks. We also improved our benchmarks a little bit:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/89/26/2625.benchmark.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-89-26/2625.benchmark.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/89/26/2625.benchmark.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-89-26/2625.benchmark.png" alt="" border="0" /></a></p>
<p>The gray bars are standard deviation, so my (really horrible) understanding of statistics means that delta's that are within the gray bars are pretty much meaningless. I'm not sure if we really did regress mono-binarytrees or not, but I'm guessing probably not. I do know that we improved a couple things that should help mono-fasta and mono-knucleotide, but the mono-chameneos-redux delta was unexpected.</p>
<p>Anyway, I hope this helps a little. I'm headed home for the evening, as my adrenaline buzz from trying to get everything done in time for Jay's talk is fading fast, and I want to watch Habib from the comfort of my couch, rather than be in traffic. Okay, I'm exaggerating: my commute is generally about 10 minutes, but I'm tired, and whiny, and there are wolves after me.</p>
<p>-Kev</p>]]></content:encoded>
    </item>
    <item>
      <title>Lies, damn lies, and benchmarks...</title>
      <link>https://docs.microsoft.com/archive/blogs/clrcodegeneration/lies-damn-lies-and-benchmarks</link>
      <pubDate>Wed, 26 Feb 2014 10:07:00 GMT</pubDate>
      <dc:creator><![CDATA[Kevin Frei]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/clrcodegeneration/2014/02/26/lies-damn-lies-and-benchmarks/</guid>
      <description><![CDATA[Hi, Folks! We just released RyuJIT CTP2, complete with a magical graph indicating the performance of...]]></description>
      <content:encoded><![CDATA[<p>Hi, Folks! We just released RyuJIT CTP2, complete with a magical graph indicating the performance of the new 64 bit JIT compiler as compared to JIT64. I figured I'd describe the benchmarks we're currently tracking in a little more detail, and maybe include some source code where it's code that it's okay to share. Before that, though, let&rsquo;s see that magical graph again (Positive numbers indicate CTP2 does better that JIT64):&nbsp;</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/89/26/1830.jit64.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-89-26/1830.jit64.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/89/26/1830.jit64.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-89-26/1830.jit64.png" alt="" border="0" /></a></p>
<p>And, just for fun, let&rsquo;s include one more (positive numbers indicate CTP2 does better than CTP1):</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/89/26/6740.ctp1.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-89-26/6740.ctp1.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/89/26/6740.ctp1.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-89-26/6740.ctp1.png" alt="" border="0" /></a></p>
<p>First things first: there is no rhyme or reason to the order of the benchmarks we're running. They're in a list in a file, so that's the order they run. The methodology used to measure performance is pretty straight forward: each benchmark is run once, as a "warm-up" run (get input files in the cache, etc...), then run 25 times. The average of those subsequent 25 runs is what's reported. The standard deviation is also calculated,&nbsp;in an effort to make it easier to detect noise from actual performance differences. The benchmarks are run on a <a href="https://ark.intel.com/products/76086/Intel-Core-i7-4850HQ-Processor-6M-Cache-up-to-3_50-GHz">Core i7 4850HQ</a>, 4G RAM, an SSD,&nbsp;on-board video,&nbsp;running Windows 8.1. Nothing too fancy, just a relatively up-to-date piece of hardware that does a reasonable job of spanning laptop/mobile performance and workstation/server performance. Every benchmark is an IL-only, non-32-bit-preferred binary, so they'll all run with either a 32 or 64 bit runtime.</p>
<p>Now that you have a crystal clear understanding of how we're running the benchmarks, let's talk about them in left-to-right order. I'll warn you before I start: some benchmarks are better than others, and I have spent more time looking at some benchmarks more than others. That will become incredibly obvious as the discussion continues.</p>
<p>Roslyn:<br />this one is hopefully pretty self-explanatory. We perform a &ldquo;self-build&rdquo; of the <a href="https://msdn.microsoft.com/en-us/vstudio/roslyn.aspx">Roslyn C# compiler</a>: the Roslyn C# compiler reads in the C# source code of Roslyn, and generates the Roslyn compiler binaries. It&rsquo;s using bits later than what are publicly available, and the source code isn&rsquo;t publicly available, so this one is pretty hard for other folks to reproduce :-(. The timer is an 'external' timer: the self-build is launched by a process that has a timer, so the time reported includes process launch, JIT time, and code execution time. This one is probably the single largest benchmark we have. The improvement in JIT compile time (Throughput) accounts for more than half of the improved performance. Outside of improved throughput, there are places where we generate better code for Roslyn (code quality: CQ for short) and places where we&rsquo;re worse. We&rsquo;re continuing to look into performance of this code. Since the Roslyn team works closely with the .NET Runtime &amp; Framework team, we have lots of experts in that code base nearby. One final note on Roslyn: it may appear at first glance that we did nothing here between CTP1 and CTP2, but the CTP1 build didn&rsquo;t work properly. So we fixed a few bugs there to get where we are now.</p>
<p>System.XML:<br />this one should probably not really be included for RyuJIT CTP runs. It's running the XML parser against an input XML file. The reason the data isn't particularly interesting is because the XML parser is in System.XML.dll, which is NGen'ed, which means that it's actually just running code that JIT64 produced, where RyuJIT is only compiling the function that's calling the parser. Internally, we can use RyuJIT for NGen as well, so that's why it's there, but it's not showing anything observable for CTP releases of RyuJIT.</p>
<p>SharpChess:<br />This is an open source C# chess playing application written by Peter Hughes. You can download the latest version from <a href="https://www.sharpchess.com">https://www.sharpchess.com</a>. We&rsquo;re using version 2.5.2. It includes a very convenient mode for benchmarking which reads in a position, then prints out how many milliseconds it takes to calculate the next move. RyuJIT does a respectable job, keeping pace with JIT64 just fine, here.</p>
<p>V8-*:<br />these benchmarks are transliterations of JavaScript benchmarks that are part of the V8 JavaScript performance suite. A former JIT developer did the transliteration many years ago, and that&rsquo;s about the extent of my understanding of these benchmarks, exception that I assume that v8-crypto does something with cryptography. Of the 3, <a href="https://kscdg.codeplex.com/SourceControl/latest#JIT-Benchmarks/richards.cs">Richards</a>&nbsp;and <a href="https://kscdg.codeplex.com/SourceControl/latest#JIT-Benchmarks/crypto.cs">Crypto</a>&nbsp;have fairly innocuous licenses, so I&rsquo;ve put them on my CodePlex&nbsp;site for all to enjoy. DeltaBlue due to lincensing restrictions can&rsquo;t be hosted on CodePlex.</p>
<p>Bio-Mums:<br />This is a benchmark picked up from Microsoft Research&rsquo;s &ldquo;Biological Foundation&rdquo; system several years ago. Since we grabbed it, they&rsquo;ve <a href="https://bio.codeplex.com/">open-sourced</a> the work. Beyond that, I know it has something to do with biology, but just saying that word makes my brain shudder, so you&rsquo;ll have to poke around on the web for more details.</p>
<p>Fractals:<br />Matt Grice, one of the RyuJIT Developers, wrote this about a year ago. It calculates the Mandelbrot set and a specific Julia set using a complex number struct type. With Matt&rsquo;s permission, I&rsquo;ve put the source code on my CodePlex site, so you can <a href="https://kscdg.codeplex.com/SourceControl/latest#JIT-Benchmarks/FractalPerf.cs">download</a> it and<br />marvel at its beauty, its genius. This is a reasonable micro-benchmark for floating point basics, as well as abstraction cost. RyuJIT is pretty competitive with JIT64 on floating point basics, but RyuJIT demolishes JIT64 when it comes to abstraction costs, primarily due to Struct Promotion. The graph isn&rsquo;t accurate for this benchmark, because RyuJIT is just over 100% (2X) faster than JIT64 on this one. But if that value were actually visible, nothing else would look signficant, so I just cropped the Y axis.</p>
<p>BZip2:<br />This is measuring the time spent zip&rsquo;ing the IL disassembly of mscorlib.dll. RyuJIT is a few percent slower than JIT64. This benchmark predates the .NET built-in support for ZIP, so it uses the SharpZip library.</p>
<p>Mono-*:<br />We grabbed these benchmarks after CTP1 shipped. A blog commenter pointed us at them, and they were pretty easy to integrate into our test system. They come from &ldquo;<a href="https://benchmarksgame.alioth.debian.org/">The Computer Language Benchmarks Game</a>&rdquo;. When we started measuring them, we were in pretty bad shape, but most have gone to neutral. We do still have a handful of losses, but we&rsquo;re still working. For details about each benchmark, just hit up the original website. They&rsquo;re all pretty small applications, generally stressing particular optimization paths, or particular functionality. Back when JIT64 started, it was originally tuned to optimize C++/CLI code, and focused on the Spec2000 set of tests, compiled as managed code. This generally tuned for optimizations that pay off in this set of benchmarks, as well. The only benchmark out of the batch that you won&rsquo;t find on the debian website is pi-digits. The implementation from the original site used p/invoke to use the GMP high-precision numeric package. I implemented it using .NET&rsquo;s BigInteger class instead. Again, you can find the<br />code on my <a href="https://kscdg.codeplex.com/SourceControl/latest#JIT-Benchmarks/pi-digits.cs">codeplex site</a>.</p>
<p>SciMark:<br />This one is pretty self-explanatory. SciMark&rsquo;s been around a long time, and there&rsquo;s a pretty reasonable C# port done back in Rotor days that now lives <a href="https://code.google.com/p/scimark-csharp/">here</a>. It&rsquo;s a set of scientific computations, which means heavy floating point, and heavy array manipulation. Again, we&rsquo;re doing much better than we were with CTP1, but RyuJIT still lags behind JIT64 by a bit. We&rsquo;ve got some improvements that didn&rsquo;t quite make it in for CTP2, but will be included in future updates.</p>
<p>FSharpFFT:<br />Last, but not least. When we released CTP1, there was some consternation about how F# would perform, because JIT64 did a better job of optimizing tail-calls than JIT32 did. Jon Harrup gave me an F# implementation of a Fast Fourier Transform, which I dumped into our benchmark suite with virtually no understanding of the code at all. We&rsquo;ve made some headway, and are now beating JIT64 by a reasonable margin. One item worth mentioning for you F# fans out there: We&rsquo;ve got the F# self-build working with RyuJIT, which was pretty excellent. Maybe we&rsquo;ll start running that one as a benchmark, too!</p>
<p>There you have it: a quick run through of the benchmarks we run. Having read through it anyone that paid attention should be able to tell that I don&rsquo;t write code, I just run the team :-). If folks would like more details about anything post questions below, and I&rsquo;ll see what I can do to get the engineers that actually write the code to answer them.</p>
<p>Happy benchmarking!</p>
<p>-Kev</p>]]></content:encoded>
    </item>
    <item>
      <title>RyuJIT FAQ is on the .NET Blog</title>
      <link>https://docs.microsoft.com/archive/blogs/clrcodegeneration/ryujit-faq-is-on-the-net-blog</link>
      <pubDate>Mon, 18 Nov 2013 10:04:39 GMT</pubDate>
      <dc:creator><![CDATA[Kevin Frei]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/clrcodegeneration/2013/11/18/ryujit-faq-is-on-the-net-blog/</guid>
      <description><![CDATA[Go forth and read it to see if it answers your questions:...]]></description>
      <content:encoded><![CDATA[<p>Go forth and read it to see if it answers your questions: <a href="https://blogs.msdn.com/b/dotnet/archive/2013/11/18/ryujit-net-jit-compiler-ctp1-faq.aspx">https://blogs.msdn.com/b/dotnet/archive/2013/11/18/ryujit-net-jit-compiler-ctp1-faq.aspx</a></p>
<p>One thing that's buried in the FAQ: we fixed bugs that people reported, so if you uninstall RyuJIT CTP1, <a title="re-download it" href="https://aka.ms/RyuJIT"> re-download</a> it and reinstall it, you'll get an ever so slightly less buggy version!</p>
<p>If&nbsp;the FAQ&nbsp;doesn't answer your questions, I'll answer other questions over here. Fewer people read this one, so I'll get myself into less trouble than my previous Answers to Questions :-)</p>
<p>-Kev</p>
<p>&nbsp;</p>]]></content:encoded>
    </item>
  </channel>
</rss>