Condividi tramite


Ottimizzazione e debug JIT

Quando si fa il debug del codice, è più semplice se il codice non è ottimizzato. Quando il codice è ottimizzato, il compilatore e il runtime apportano modifiche al codice CPU generato in modo che venga eseguito più velocemente, ma ha un mapping meno diretto al codice sorgente originale. Se il mapping è meno diretto, i debugger spesso non sono in grado di indicare il valore delle variabili locali e i passaggi del codice e i punti di interruzione potrebbero non funzionare come previsto.

Annotazioni

Per altre informazioni sul debug JIT (Just-In-Time), vedere Debug con il Just-In-Time Debugger in Visual Studio.

Funzionamento delle ottimizzazioni in .NET

In genere, la configurazione della build di rilascio crea codice ottimizzato e la configurazione della build di debug non lo fa. La Optimize proprietà MSBuild controlla se al compilatore viene chiesto di ottimizzare il codice.

Nell'ecosistema .NET il codice viene trasformato da istruzioni di origine a CPU in un processo in due passaggi: prima, il compilatore C# converte il testo digitato in un formato binario intermedio denominato MSIL e scrive il codice MSIL in .dll file. Successivamente, il runtime .NET converte questo MSIL in istruzioni della CPU. Entrambi i passaggi possono essere ottimizzati in qualche modo, ma il secondo passaggio eseguito dal runtime .NET esegue le ottimizzazioni più significative.

Opzione 'Suppress JIT optimization on module load (Managed only)' (Elimina l'ottimizzazione JIT al caricamento del modulo (solo gestito)"

Il debugger espone un'opzione che controlla cosa accade quando una DLL compilata con ottimizzazioni abilitate carica all'interno del processo di destinazione. Se questa opzione è deselezionata (stato predefinito), quando .NET Runtime compila il codice MSIL nel codice CPU, lascia abilitate le ottimizzazioni. Se l'opzione è selezionata, il debugger richiede che le ottimizzazioni siano disabilitate.

È possibile configurare l'opzione Elimina ottimizzazione JIT al caricamento del modulo (solo gestito) nel riquadro Opzioni strumenti>, nella sezione Tutte le impostazioni>generale>:

Screenshot dell'opzione Sopprimi l'ottimizzazione JIT nel debug del caricamento del modulo.

È possibile configurare l'opzione Elimina ottimizzazione JIT al caricamento del modulo (solo gestito) nella finestra di dialogoOpzioni>, nella sezioneDebug>:

Sopprimere l'ottimizzazione JIT

Quando è necessario selezionare l'opzione 'Elimina ottimizzazione JIT'?

Selezionare questa opzione quando sono state scaricate le DLL da un'altra origine, ad esempio un pacchetto NuGet e si vuole eseguire il debug del codice in questa DLL. Per il corretto funzionamento dell'eliminazione, è necessario trovare anche il file simbolo (con estensione pdb) per questa DLL.

Se si è interessati solo al debug del codice che si sta creando in locale, è consigliabile lasciare deselezionata questa opzione, come in alcuni casi, l'abilitazione di questa opzione rallenta notevolmente il debug. Esistono due motivi per il rallentamento:

  • Il codice ottimizzato viene eseguito più velocemente. Se si disattivano le ottimizzazioni per un numero elevato di codice, l'impatto sulle prestazioni può aumentare.
  • Se Just My Code è abilitato, il debugger non prova nemmeno a caricare i simboli per le DLL ottimizzate. La ricerca dei simboli può richiedere molto tempo.

Limitazioni dell'opzione 'Elimina ottimizzazione JIT'

Esistono due scenari in cui l'abilitazione di questa opzione non funziona:

  • Se si collega il debugger a un processo già in esecuzione, questa opzione non ha alcun effetto sui moduli già caricati al momento del collegamento del debugger.
  • Questa opzione non ha alcun effetto sulle DLL precompilate (o ngen'ed) nel codice nativo. Tuttavia, è possibile disabilitare l'utilizzo del codice precompilato avviando il processo con la variabile di ambiente 'COMPlus_ReadyToRun' impostata su '0'. Questo approccio indica al runtime di .NET Core di disabilitare l'uso di immagini precompilate, che forza il runtime a compilare il codice framework JIT.

    Se si ha come destinazione .NET Framework, aggiungere la variabile di ambiente "COMPlus_ZapDisable" e impostarla su "1".

Impostare "COMPlus_ReadyToRun": "0" aggiungendolo a ogni profilo nel file Proprietà\launchSettings.jssu:

{
  "iisSettings": {
    "windowsAuthentication": false,
    "anonymousAuthentication": true,
    "iisExpress": {
      "applicationUrl": "http://localhost:59694/",
      "sslPort": 44320
    }
  },
  "profiles": {
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development",
        "COMPlus_ReadyToRun": "0"
      }
    },
    "HttpLoggingSample": {
      "commandName": "Project",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development",
        "COMPlus_ReadyToRun": "0"
      },
      "applicationUrl": "https://localhost:5001;http://localhost:5000"
    }
  }
}