Подтвердить что ты не робот

Оптимизация локальной переменной .NET

Я читал через источники .NET, когда нашел это:

// Constructs a Decimal from an integer value.
//
public Decimal(int value) {
    //  JIT today can't inline methods that contains "starg" opcode.
    //  For more details, see DevDiv Bugs 81184: x86 JIT CQ:
    //  Removing the inline striction of "starg".
    int value_copy = value;  
    if (value_copy >= 0) {
        flags = 0;
    }
    else {
        flags = SignMask;
        value_copy = -value_copy;
    }
    lo = value_copy;
    mid = 0;
    hi = 0;
}

Как вы можете видеть, конструктор десятичной структуры копирует аргумент метода локальной переменной, а не использует ее напрямую. Мне было интересно, что означает комментарий и как оно относится к производительности и оптимизации?

Мое предположение заключается в том, что как только вы хотите изменить существующий аргумент, метод больше не может быть привязан?

http://referencesource.microsoft.com/#mscorlib/system/decimal.cs#f9a4da9d6e110054#references

4b9b3361

Ответ 1

Мое предположение заключается в том, что если вы хотите изменить существующий аргумент, метод больше не может быть inlined?

Короткий ответ: Ваша догадка правильная (если этот комментарий к исходному коду по-прежнему правдивый сегодня).

//  JIT today can't inline methods that contains "starg" opcode.

"JIT" - это часть среды выполнения .NET, которая переводит промежуточный язык (IL ) (например, "байт-код .NET" ) на ваш язык ассемблера. Только тогда код может быть выполнен на вашем компьютере. JIT выполняет этот метод перевода по методу и только тогда, когда это действительно необходимо: всякий раз, когда метод сначала вызывается, он сначала скомпилируется до фактического языка ассемблера "точно в срок" (JIT).

Компилятор С# не создает язык сборки для вашей компьютерной архитектуры сразу; вместо этого он генерирует промежуточный язык, который является своего рода языком ассемблера для абстрактной машины стека ( который был определен в ECMA 334 международный стандарт).

Например, присваивания параметра (в вашем примере: value) будут переведены компилятором С# на команду IL, называемую starg ( "хранить аргумент" ).

В комментарии в основном говорится, что если метод содержал такое назначение (value = …), тогда JIT в настоящее время не сможет "встроить" его. "Вложение метода" означает, что вместо генерации инструкций вызова к методу (т.е. ветки команд в другое местоположение кода), JIT вместо этого введет метод всего тела в том месте, где он вызывается. Обычно это делается для оптимизации скорости выполнения, потому что нет необходимости в ветвлении/прыжке, и, кроме того, я предполагаю, что новый фрейм стека тоже не должен быть установлен.

Вместо этого вместо локальной переменной (value_copy = …) это ограничение JIT обойдется, потому что присвоения локальным переменным приводят к генерации другой команды IL: stloc ( "хранить локальную переменную" ).

См. также: