XmlSerializer startup HUGE performance loss on 64bit systems

六月ゝ 毕业季﹏ 提交于 2019-11-27 12:45:24

I don't know if this is related at all, but I had an issue with XSLT and found those rather interesting comments by Microsoft about the 64-Bit JITter:

The root of the problem is related to two things: First, the x64 JIT compiler has a few algorithms that are quadratically scaling. One of them is the debug info generator, unfortunately. So for very large methods, it really gets out of control.

[...]

some algorithms in the 64 bit JIT that have polynomial scaling. We're actually working on porting the 32 bit JIT compiler to x64, but that won't see the light of day until the next side-by-side release of the runtime (as in "2.0 & 4.0 run side-by-side, but 3.0/3.5/3.5SP1 were 'in-place' releases). I've switched this over to a 'suggestion' so I can keep it attached to the JIT-throughput work item to make sure this is fixed when the newly ported JIT is ready to ship.

Again, this is about a completely different issue, but it appears to me that the 64-Bit JITter comments are universal.

UPDATE:

I was able to reproduce this, investigation shows that most time was spent in JIT-compiler:

JittingStarted: "Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderFoo", "Read2_Foo", "instance class SerializersTester.Foo"

You can easily proof that without any profiler tool.

  • Generate *.XmlSerializers.dll via sgen for x86 and x64 targets
  • Generate native images via ngen.

You can notice x64 generation will be much more slower in compare with x86 assembly

The exact reason hides in x64 JIT-internals (BTW it completely different from x86) and unfortunately I don't have enough spare time to find it.

To avoid such performance loss you can generate serializer's assembly via sgen, reference it and compile to native image via ngen during application setup on end user PC.

To clarify the "XmlSerialization.compile" this is what it's happening:

If we run the code without a .config file on 64 bit it's slow.

If we add the following section to the .config file for the application

<configuration>
   <system.diagnostics>
     <switches>
        <add name="XmlSerialization.Compilation" value="4"/>
     </switches>
   </system.diagnostics>
</configuration>

The result is the following:

  • .cs file, DLL and PDB file for the serializer are left in the temp folder
  • serializer start quicky, it's still slower than on 32 bit but definitively acceptable (1-2 seconds instead of 60)

Maybe creating the DLL in debug mode (because there are PDB files available) change the behavior of the JIT compiler making it fast again...

Microsoft has known about this since the release of the 64 bit .NET:

http://connect.microsoft.com/VisualStudio/feedback/details/508748/memory-consumption-alot-higher-on-x64-for-xslcompiledtransform-transform-then-on-x86

From MSFT: "the x64 JIT compiler has a few algorithms that are quadratically scaling. ... it's been something that we've seen a number of times since the 64 bit framework first released in 2005." and

"This issue is a) known, and b) not really trivial to address. It's a design issue with the 64 bit JIT. We're in the early stages of replacing our 64-bit JIT implementation, so it will eventually get address, but not in the CLR 4.0 timeframe, unfortunately."

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!