SORU
13 Ocak 2010, ÇARŞAMBA


.NET JİT potansiyel hata?

Aşağıdaki kodu Visual Studio içinde serbest çalışan ve Visual Studio dışında serbest çalışan farklı çıktılar verir. Visual Studio 2008 kullanarak ve hedef oldum .NET 3.5. Ayrıca denedim .NET 3.5 SP1.

Visual Studio dışında çalışan, TAM zamanında devreye girer. Atladığım veya (b) JİT aslında hata. (a) bir ince C oluyor# Bu TAM ters gidebilecek şüpheli değilim, ama diğer ihtimalleri azalıyor

Visual Studio içinde çalışırken, çıkış:

    0 0,
    0 1,
    1 0,
    1 1,

Visual Studio dışında serbest çalışan çıktı:

    0 2,
    0 2,
    1 2,
    1 2,

Sebebi nedir?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Test
{
    struct IntVec
    {
        public int x;
        public int y;
    }

    interface IDoSomething
    {
        void Do(IntVec o);
    }

    class DoSomething : IDoSomething
    {
        public void Do(IntVec o)
        {
            Console.WriteLine(o.x.ToString()   " "   o.y.ToString() ",");
        }
    }

    class Program
    {
        static void Test(IDoSomething oDoesSomething)
        {
            IntVec oVec = new IntVec();
            for (oVec.x = 0; oVec.x < 2; oVec.x  )
            {
                for (oVec.y = 0; oVec.y < 2; oVec.y  )
                {
                    oDoesSomething.Do(oVec);
                }
            }
        }

        static void Main(string[] args)
        {
            Test(new DoSomething());
            Console.ReadLine();
        }
    }
}

CEVAP
13 Ocak 2010, ÇARŞAMBA


JİT iyileştirici bir hata. İç döngü çözümü ama oVec güncelleme değil.y değeri doğru

      for (oVec.x = 0; oVec.x < 2; oVec.x  ) {
0000000a  xor         esi,esi                         ; oVec.x = 0
        for (oVec.y = 0; oVec.y < 2; oVec.y  ) {
0000000c  mov         edi,2                           ; oVec.y = 2, WRONG!
          oDoesSomething.Do(oVec);
00000011  push        edi  
00000012  push        esi  
00000013  mov         ecx,ebx 
00000015  call        dword ptr ds:[00170210h]        ; first unrolled call
0000001b  push        edi                             ; WRONG! does not increment oVec.y
0000001c  push        esi  
0000001d  mov         ecx,ebx 
0000001f  call        dword ptr ds:[00170210h]        ; second unrolled call
      for (oVec.x = 0; oVec.x < 2; oVec.x  ) {
00000025  inc         esi  
00000026  cmp         esi,2 
00000029  jl          0000000C 

Hata oVec izin kaybolur.çok fazla aramalar için 4, y artışı göz önüne sermek.

Tek çözüm bu

  for (int x = 0; x < 2; x  ) {
    for (int y = 0; y < 2; y  ) {
      oDoesSomething.Do(new IntVec(x, y));
    }
  }

GÜNCELLEME: Ağustos ayında tekrar kontrol 2012, bu hata, sürüm 4.0.30319 Jetta ile giderilmiştir. Ama v2 de mevcut.0.50727 titreme. Bu kadar uzun süre sonra eski sürümü bu düzeltme yapacaklar Olası görünüyor.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Chaoticmoogle

    Chaoticmoogl

    13 ŞUBAT 2006
  • IGN

    IGN

    19 EYLÜL 2006
  • Michael Zhang

    Michael Zhan

    8 EYLÜL 2012