C# может распараллелить, действительно кэшируют значение и игнорируют изменения в том значении на других потоках?

Простым способом было бы использовать фреймворк PHP, такой как CodeIgniter или Laravel , которые имеют встроенные функции, такие как фильтрация и активная запись, так что вам не нужно беспокоиться об этих нюансах.

25
задан Community 23 May 2017 в 12:34
поделиться

3 ответа

Точка: это могло бы работать, но это не , гарантировал для работы спецификацией. Что люди обычно, после код, который работает по правильным причинам, вместо того, чтобы работать комбинацией счастливой случайности компилятора, времени выполнения и JIT, который мог бы изменение между версиями платформы, физическим ЦП, платформой и вещами как x86 по сравнению с x64.

Понимание модели памяти является очень очень сложной областью, и я не утверждаю, что был экспертом; но люди, которые являются настоящие эксперты в этой области, уверяют меня, что поведение, которое Вы видите, не гарантируется.

можно отправить как много рабочих примеров как Вам угодно, но к сожалению который не доказывает очень кроме "его, обычно работает". Конечно, не оказывается, что это , гарантировал для работы. Это только взяло бы единственный контрпример для опровержения, но нахождение его является проблемой...

нет, у меня нет для вручения.

<час>

Обновление с повторяемым контрпримером:

using System.Threading;
using System;
static class BackgroundTaskDemo
{
    // make this volatile to fix it
    private static bool stopping = false;

    static void Main()
    {
        new Thread(DoWork).Start();
        Thread.Sleep(5000);
        stopping = true;


        Console.WriteLine("Main exit");
        Console.ReadLine();
    }

    static void DoWork()
    {
        int i = 0;
        while (!stopping)
        {
            i++;
        }

        Console.WriteLine("DoWork exit " + i);
    }
}

Вывод:

Main exit

, но все еще выполнение, в полном ЦП; обратите внимание, что stopping был установлен на true этой точкой. Эти ReadLine то, так, чтобы процесс не завершался. Оптимизация, кажется, зависит от размера кода в цикле (следовательно i++). Это только работает в режиме "выпуска", очевидно. Добавьте volatile, и все это хорошо работает.

49
ответ дан Marc Gravell 28 November 2019 в 20:38
поделиться

Этот пример включает собственный x86-код как комментарии, чтобы продемонстрировать, что переменная управления ('stopLooping') кэшируется.

Изменение 'stopLooping' к энергозависимому для "зафиксированного" его.

Это было создано с Visual Studio 2008 как Сборка конечных версий и выполнение без отладки.

 using System;

 using System.Threading;

/* A simple console application which demonstrates the need for 
 the volatile keyword and shows the native x86 (JITed) code.*/

static class LoopForeverIfWeLoopOnce
{

    private static bool stopLooping = false;

    static void Main()
    {
        new Thread(Loop).Start();
        Thread.Sleep(1000);
        stopLooping = true;
        Console.Write("Main() is waiting for Enter to be pressed...");
        Console.ReadLine();
        Console.WriteLine("Main() is returning.");
    }

    static void Loop()
    {
        /*
         * Stack frame setup (Native x86 code):
         *  00000000  push        ebp  
         *  00000001  mov         ebp,esp 
         *  00000003  push        edi  
         *  00000004  push        esi  
         */

        int i = 0;
        /*
         * Initialize 'i' to zero ('i' is in register edi)
         *  00000005  xor         edi,edi 
         */

        while (!stopLooping)
            /*
             * Load 'stopLooping' into eax, test and skip loop if != 0
             *  00000007  movzx       eax,byte ptr ds:[001E2FE0h] 
             *  0000000e  test        eax,eax 
             *  00000010  jne         00000017 
             */
        {
            i++;
            /*
             * Increment 'i'
             *  00000012  inc         edi  
             */

            /*
             * Test the cached value of 'stopped' still in
             * register eax and do it again if it's still
             * zero (false), which it is if we get here:
             *  00000013  test        eax,eax 
             *  00000015  je          00000012 
             */
        }

        Console.WriteLine("i={0}", i);
    }
}
4
ответ дан TheSoftwareJedi 28 November 2019 в 20:38
поделиться

FWIW:

  • я имею замеченный эта компиляторная оптимизация из компилятора C++ MS (неуправляемый код).
  • я не знаю, происходит ли это в C#
  • , который Этого не произойдет при отладке (оптимизация компилятора автоматически отключена при отладке)
  • , Даже если той оптимизации не происходит теперь, Вы держите пари, что они никогда не будут представлять ту оптимизацию в будущих версиях JIT-компилятора.
2
ответ дан ChrisW 28 November 2019 в 20:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: