Почему не будет подставляемые функции C# с параметрами структуры?

Вы можете использовать colorchain.js для генерации последовательности цветов с различными оттенками.

5
задан Fantius 26 June 2009 в 15:40
поделиться

5 ответов

Как сказал Джон, это очень старый пост. Я могу подтвердить это в следующем коде:

using System;
using System.Runtime.CompilerServices;

struct MyStruct
{
   public MyStruct(int p)
   {
      X = p;
   }
   public int X;

   // prevents optimization of the whole thing to a constant.
   [MethodImpl(MethodImplOptions.NoInlining)]
   static int GetSomeNumber()
   {
       return new Random().Next();
   }

   static void Main(string[] args)
   {
      MyStruct x = new MyStruct(GetSomeNumber());
      // the following line is to prevent further optimization:
      for (int i = inlinetest(x); i != 100 ; i /= 2) ; 
   }

   static int inlinetest(MyStruct x)
   {
      return x.X + 1;
   }
}

метод inlinetest встроен.

Разборка основного метода:

; set up the stack frame:
00000000  push        ebp
00000001  mov         ebp,esp 

; calls GetSomeNumber:
00000003  call        dword ptr ds:[005132D8h] 

; inlined function:
00000009  inc         eax  

; the dummy for loop:
0000000a  cmp         eax,64h 
0000000d  je          0000001B 
0000000f  sar         eax,1 
00000011  jns         00000016 
00000013  adc         eax,0 
00000016  cmp         eax,64h 
00000019  jne         0000000F 
0000001b  pop         ebp  
0000001c  ret 

Я тестировал это на x86 .NET Framework 3.5 SP1 в Windows 7 x64 RC.

Как я полагал, нет ничего плохого во встраивании методов с параметрами struct . Вероятно, JIT в то время не была достаточно умной.

4
ответ дан 15 December 2019 в 06:33
поделиться

Мое первое предположение состоит в том, что это потребует изменения размера кадра стека, созданного для этого метода. При использовании ссылочного типа (класса) фрейм стека должен позволять хранить указатель (на объект в куче), тогда как со структурой ALL примитивные поля структур должны быть добавлены к отпечатку фреймов стека.

0
ответ дан 15 December 2019 в 06:33
поделиться

Вот лучшая статья, описывающая, почему некоторые методы не будут встроены. И здесь - это запись обратной связи MS Connect с комментариями, которые включают результаты тестов (FWIW)

2
ответ дан 15 December 2019 в 06:33
поделиться

Как вы заметили, это проблема типа значения по сравнению с типом ссылки . Представьте, что у вас есть функция с аргументом типа значения (скажем, int), и вы изменяете эту переменную в функции . Очевидно, это не имеет побочных эффектов в вызывающей функции , поскольку вы передали по значению, а не по ссылке.

Теперь представьте, что вы встраиваете тот же код. Внезапно ваша переменная изменяется в вызывающей функции ! Не то, что вы намеревались.

Вероятно, вы можете убедить себя, продумав тот же сценарий со ссылочным типом, что встраивание не имеет проблем для параметров by-ref - изменение исходной функции имеет те же последствия. как изменение встроенной версии этой функции.

Вот почему это не разрешено, но я согласен с тем, что у вас должен быть какой-то способ сообщить компилятору, что вы «гарантируете», что ваша функция не имеет побочных эффектов на аргументы типа значения. Во многих случаях это может быть полезно с точки зрения производительности.

Между прочим, вы всегда можете объявить уровень модуля int и полностью обойти аргумент :) Гораздо хуже, но вы в конечном итоге встраиваете рассматриваемую функцию.

Что бы вы ни решили сделать, удачи!

РЕДАКТИРОВАТЬ: Я только что вспомнил, что на Irix (операционная система SGI) был древний компилятор C, который на самом деле имел для этого параметр компилятора, позволяющий «принудительно» встраивать. Так что это можно сделать, но я согласен с сделанным здесь выбором, выбрав вариант по умолчанию, менее подверженный ошибкам.

что ваша функция не имеет побочных эффектов для аргументов типа значения. Во многих случаях это может быть полезно с точки зрения производительности.

Между прочим, вы всегда можете объявить уровень модуля int и полностью обойти аргумент :) Гораздо хуже, но вы в конечном итоге встраиваете рассматриваемую функцию.

Что бы вы ни решили сделать, удачи!

РЕДАКТИРОВАТЬ: Я только что вспомнил, что на Irix (операционная система SGI) был древний компилятор C, который на самом деле имел для этого параметр компилятора, позволяющий «принудительно» встраивать. Так что это можно сделать, но я согласен с сделанным здесь выбором, выбрав вариант по умолчанию, менее подверженный ошибкам.

что ваша функция не имеет побочных эффектов для аргументов типа значения. Во многих случаях это может быть полезно с точки зрения производительности.

Между прочим, вы всегда можете объявить уровень модуля int и полностью обойти аргумент :) Гораздо хуже, но вы в конечном итоге встраиваете рассматриваемую функцию.

Что бы вы ни решили сделать, удачи!

РЕДАКТИРОВАТЬ: Я только что вспомнил, что на Irix (операционная система SGI) был древний компилятор C, который на самом деле имел для этого параметр компилятора, позволяющий «принудительно» встраивать. Так что это можно сделать, но я согласен с сделанным здесь выбором, выбрав вариант по умолчанию, менее подверженный ошибкам.

но в конечном итоге вы бы встраивали рассматриваемую функцию.

Что бы вы ни решили делать, удачи!

РЕДАКТИРОВАТЬ: Я только что вспомнил, что на Irix (операционная система SGI) был древний компилятор C, который на самом деле имел параметр компилятора для этого, позволяющий "принудительно" встраивать. Так что это можно сделать, но я согласен с сделанным здесь выбором, выбрав вариант по умолчанию, менее подверженный ошибкам.

но в конечном итоге вы бы встраивали рассматриваемую функцию.

Что бы вы ни решили делать, удачи!

РЕДАКТИРОВАТЬ: Я только что вспомнил, что на Irix (операционная система SGI) был древний компилятор C, который на самом деле имел параметр компилятора для этого, позволяющий "принудительно" встраивать. Так что это можно сделать, но я согласен с сделанным здесь выбором, выбрав вариант по умолчанию, менее подверженный ошибкам.

-3
ответ дан 15 December 2019 в 06:33
поделиться

Небольшое пояснение. В этом блоге не обсуждается, что C # будет или не будет встроено. Он обсуждает, что JITer будет или не будет встраивать.

Я не знаю, почему JITer не встраивает методы со структурами в качестве формальных параметров.
Однако я относительно уверен, что если они не будут встраивать метод с параметром структуры, то создание структуры с помощью ref не изменит это решение.

0
ответ дан 15 December 2019 в 06:33
поделиться
Другие вопросы по тегам:

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