Desempenho muito baixo da tarefa assíncrona executada no pool de threads em .Net nativo

Eu observei uma diferença estranha no código nativo gerenciado vs .Net. Eu tenho um trabalho pesado redirecionado para o pool de threads. Ao executar o aplicativo no código gerenciado, tudo funciona sem problemas, assim que eu ligo a compilação nativa - a tarefa é executada algumas vezes mais devagar e mais devagar que interrompe o encadeamento da interface do usuário (acho que a CPU está sobrecarregada).

Aqui estão duas capturas de tela da saída de depuração, a da esquerda é do código gerenciado e a da direita é da compilação nativa. Como você pode ver, o tempo consumido pela tarefa da interface do usuário é quase o mesmo nos dois casos, até o momento em que o trabalho de conjunto de threads é iniciado - então, na versão gerenciada, o tempo decorrido da UI aumenta (na verdade, a UI é bloqueada e você não pode executar nenhuma ação). Os horários do trabalho do conjunto de threads falam por si.

O código de exemplo para reproduzir o problema:

private int max = 2000;
private async void UIJob_Click(object sender, RoutedEventArgs e)
{
    IProgress<int> progress = new Progress<int>((p) => { MyProgressBar.Value = (double)p / max; });
    await Task.Run(async () => { await SomeUIJob(progress); });
}

private async Task SomeUIJob(IProgress<int> progress)
{
    Stopwatch watch = new Stopwatch();
    watch.Start();
    for (int i = 0; i < max; i++)
    {
        if (i % 100 == 0) { Debug.WriteLine($"     UI time elapsed => {watch.ElapsedMilliseconds}"); watch.Restart(); }
        await Task.Delay(1);
        progress.Report(i);
    }
}

private async void ThreadpoolJob_Click(object sender, RoutedEventArgs e)
{
    Debug.WriteLine("Firing on Threadpool");
    await Task.Run(() =>
   {
       double a = 0.314;
       Stopwatch watch = new Stopwatch();
       watch.Start();
       for (int i = 0; i < 50000000; i++)
       {
           a = Math.Sqrt(a) + Math.Sqrt(a + 1) + i;
           if (i % 10000000 == 0) { Debug.WriteLine($"Threadpool -> a value = {a} got in {watch.ElapsedMilliseconds} ms"); watch.Restart(); };
       }
   });
    Debug.WriteLine("Finished with Threadpool");
}

Se você precisar de uma amostra completa - poderáfaça o download aqui.

Como eu testei, a diferença aparece no código otimizado / não otimizado, nas versões debug e release.

Alguém tem uma idéia do que pode causar o problema?

questionAnswers(1)

yourAnswerToTheQuestion