c# depuración - .NET JIT error potencial?




2 Answers

Es un error del optimizador JIT. Se está desenrollando el bucle interno pero no está actualizando el valor de oVec.y correctamente:

      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 

El error desaparece cuando dejas que OVec.y se incremente a 4, son demasiadas llamadas para desenrollar.

Una solución es la siguiente:

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

ACTUALIZACIÓN: revisado nuevamente en agosto de 2012, este error se corrigió en la versión 4.0.30319 jitter. Pero todavía está presente en la v2.0.50727 jitter. Parece poco probable que solucionen esto en la versión anterior después de tanto tiempo.

aplicación la

El siguiente código da un resultado diferente cuando se ejecuta la versión dentro de Visual Studio, y se ejecuta la versión fuera de Visual Studio. Estoy usando Visual Studio 2008 y apuntando a .NET 3.5. También he intentado .NET 3.5 SP1.

Cuando se ejecuta fuera de Visual Studio, el JIT debería activarse. O bien (a) está ocurriendo algo sutil con C # que me falta o (b) el JIT está realmente en error. Dudo que el JIT pueda salir mal, pero me estoy quedando sin otras posibilidades ...

Salida cuando se ejecuta dentro de Visual Studio:

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

Salida al ejecutar la versión fuera de Visual Studio:

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

¿Cual es la razon?

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();
        }
    }
}



Copié su código en una nueva aplicación de consola.

  • Construcción de depuración
    • Corrija la salida con el depurador y sin el depurador
  • Cambiado a la versión de lanzamiento
    • Una vez más, corregir la salida en ambas ocasiones
  • Creé una nueva configuración x86 (estoy ejecutando X64 Windows 2008 y estaba usando 'Cualquier CPU')
  • Construcción de depuración
    • Obtuvo la salida correcta tanto F5 como CTRL + F5
  • Versión de lanzamiento
    • Salida correcta con el depurador adjunto
    • Sin depurador - Obtuvo el resultado incorrecto

Así que es el x86 JIT generando incorrectamente el código. He eliminado mi texto original sobre la reordenación de los bucles, etc. Algunas otras respuestas aquí confirmaron que el JIT está desenrollando el bucle incorrectamente cuando está en x86.

Para solucionar el problema, puede cambiar la declaración de IntVec a una clase y funciona en todos los tipos.

Piensa que esto necesita irse en MS Connect ...

-1 a Microsoft!




Related


Tags

c#   jit