Сейчас на форуме: jinoweb (+6 невидимых)

 eXeL@B —› Программирование —› Сериализация вывода Pre-Jit в .NET сбоках с управляемым кодом
Посл.ответ Сообщение


Ранг: 71.9 (постоянный), 4thx
Активность: 0.040
Статус: Участник

Создано: 07 декабря 2017 10:22
· Личное сообщение · #1

Интересно как работает эта штука. Когда часть методов преобразуется в нативный код и помещается в .NET сборку. Потенциально это может сделать программу более быстрой, если часть ее кода будет заранее скомпилирована. Где бы нарыть доки и примеры использования?




Ранг: 622.6 (!), 521thx
Активность: 0.330.89
Статус: Участник
_Вечный_Студент_

Создано: 07 декабря 2017 10:35
· Личное сообщение · #2

Посмотри здесь:http://community.bartdesmet.net/blogs/bart/archive/2005/09/01/3512.aspx

-----
Give me a HANDLE and I will move the Earth.





Ранг: 71.9 (постоянный), 4thx
Активность: 0.040
Статус: Участник

Создано: 07 декабря 2017 10:50
· Личное сообщение · #3

plutos пишет:
Посмотри здесь


Это описание работы Ngen. А мне интересно, как можно реализовать такую программу:
Допустим есть сборка на управляемом коде. Я загружаю ее в утилитку, которая показывает мне список методов в сборке, я отмечаю галками нужные мне, и утилита компилирует их в нативный код, и помещает скомпилированный нативный код в эту же самую сборку. В результате получается, что часть методов в сборке на управляемом коде, а часть на неуправляемом.




Ранг: 1131.7 (!!!!), 447thx
Активность: 0.670.2
Статус: Участник

Создано: 07 декабря 2017 11:14 · Поправил: Gideon Vi
· Личное сообщение · #4

Бегло пробежался, вроде оно --> Link <--
Это если автоматом. Делать компиляцию и вручную вставлять/вызывать... ну, такое.




Ранг: 71.9 (постоянный), 4thx
Активность: 0.040
Статус: Участник

Создано: 07 декабря 2017 11:31 · Поправил: jangle
· Личное сообщение · #5

Gideon Vi пишет:
вроде оно


Нет, там JIT компиляция при старте приложения. А я хочу от нее вообще избавится. По нескольким причинам.
JIT-компиляция отнимает время при "холодном старте", JIT-компилятор плохо оптимизирует код, JIT-не использует многие SSE инструкции и т.п.

Чтобы можно было взять какой-то метод (допустим считающий FFT на непрерывно идущем потоке звуковых данных) . Получить его IL код из сборки, оттранслировать его в x86 ассемблерные инструкции (используя IL2CPU или подобный компилятор), и встроить полученный бинарник x86 обратно в управляемую сборку. И чтобы JIT больше не заходил в этот метод.




Ранг: 1131.7 (!!!!), 447thx
Активность: 0.670.2
Статус: Участник

Создано: 07 декабря 2017 11:42
· Личное сообщение · #6

поправьте, если не прав, .net не поддерживает asm-вставки.

jangle пишет:
встроить полученный бинарник x86


полученный чем?
Я правильно понимаю, ты хочешь декомпилировать отдельные функции на .net, скомпилировать их и вставить обратно? Но если в итоге у тебя есть нативный код (ведь ты же собираешься компилировать декомпилированную функцию?), зачем его обратно корячить в .net? Декомпиляй тогда и остальные функции и компилируй все в native.




Ранг: 71.9 (постоянный), 4thx
Активность: 0.040
Статус: Участник

Создано: 07 декабря 2017 11:45 · Поправил: jangle
· Личное сообщение · #7

Gideon Vi пишет:
полученный чем?


Компилятор типа IL2CPU

Я правильно понимаю, ты хочешь декомпилировать отдельные функции на .net, скомпилировать их и вставить обратно?


да

Декомпиляй тогда и остальные функции и компилируй все в native.
К сожалению вроде нет полноценных компиляторов IL в native, которые могут скомпилировать всю сборку.

Добавлено спустя 4 минуты
Gideon Vi пишет:
поправьте, если не прав, .net не поддерживает asm-вставки.


В книге Голдштейн С., Зурбалев Д., Флатов. "Оптимизация приложений на платформе .NET." есть вот такое описание:


Простейший способ выполнить произвольный машинный код в управляемом приложении (с применением легковесной программной прослойки) заключается в том, чтобы динамически сгенерировать машинный код и затем вызвать его. Ключевым здесь является метод Marshal.GetDelegateForFunctionPointer, ВОЗВращаЮЩИЙ управляемого делегата, указывающего на местоположение в неуправляемой памяти, где может храниться произвольный код. Следующий пример выделяет виртуальную память с флагом защиты execute_readwrite, позволяющим скопировать байты кода в память и затем выполнить их. Как результат, на процессоре Intel i7-860 скорость выполнения увеличивается более чем в два раза!




Ранг: 1131.7 (!!!!), 447thx
Активность: 0.670.2
Статус: Участник

Создано: 07 декабря 2017 11:53
· Личное сообщение · #8

jangle пишет:
Следующий пример


так а пример? Я такого ещё не встречал.




Ранг: 71.9 (постоянный), 4thx
Активность: 0.040
Статус: Участник

Создано: 07 декабря 2017 11:57 · Поправил: jangle
· Личное сообщение · #9

Gideon Vi пишет:
так а пример?


Code:
  1. [UnmanagedFunctionPointer(CallingConvention.StdCall)] delegate void VectorAddDelegate (float [] С, floatU B, float[] A, int length);
  2. [Dlllmport("kernel32.dll", SetLastError = true)] static extern IntPtr VirtualAlloc(IntPtr IpAddress, UIntPtr dwSize, IntPtr flAllocationType, IntPtr flProtect) ;
  3.  
  4. // Следующий массив байтов был получен с помощью ассемблера 
  5. // с поддержкой SSE - это законченная функция, принимающая 
  6. // четыре параметра (три вектора и длину) и складывающая их 
  7.  
  8. byte[] sseAssemblyBytes = {
  9.  0x8b, 0x5с, 0x24, 0x10, 0x8b, 0x74, 0x24, 0x0c, 0x8b, 0x7с, 0x24,
  10.  0x08, 0x8b, 0x4с, 0x24, 0x04, 0x31, 0xd2, 0x0f, 0x10, 0x0c, 0x97, 
  11.  OxOf, 0x10, 0x04, 0x96, OxOf, 0x58, 0xc8, OxOf, 0x11, 0x0c, 0x91,
  12.  0x83, 0xc2, 0x04, 0x39, Oxda, 0x7f, Oxea, 0xc2, 0x10, 0x00 };
  13.  
  14. IntPtr codeBuffer = VirtualAlloc(IntPtr.Zero,new UIntPtr((uint)sseAssemblyBytes.Length), 0x1000 | 0x2000, // MEM_COMMIT | MEM_RESERVE 0x40 // EXECUTE_READWRITE);
  15.  Marshal.Copy(sseAssemblyBytes, 0, codeBuffer, sseAssemblyBytes.Length);
  16.  VectorAddDelegate addVectors = (VectorAddDelegate)Marshal.GetDelegateForFunctionPointer(codeBuffer, typeof(VectorAddDelegate));
  17.  
  18. // Теперь для сложения векторов можно использовать 'addVectors'!


Добавлено спустя 38 минут
Собственно вопрос как встроить неуправляемый код в управляемую сборку.

Допустим у меня в проекте есть такой класс:

Code:
  1. public static class Adder
  2. {
  3.     public static int AddTwoNumbers(int first, int second)
  4.     {
  5.         return first + second;
  6.     }
  7. }


В скомпилированной сборке мой класс становится вот таким

Code:
  1. .method public hidebysig static int32  AddTwoNumbers(int32 first, int32 second) cil managed
  2. {
  3.   // Code size       9 (0x9)
  4.   .maxstack  2
  5.   .locals init ([0] int32 CS$1$0000)
  6.   IL_0000:  nop
  7.   IL_0001:  ldarg.0
  8.   IL_0002:  ldarg.1
  9.   IL_0003:  add
  10.   IL_0004:  stloc.0
  11.   IL_0005:  br.s       IL_0007
  12.   IL_0007:  ldloc.0
  13.   IL_0008:  ret
  14. // end of method Adder::AddTwoNumbers



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


 eXeL@B —› Программирование —› Сериализация вывода Pre-Jit в .NET сбоках с управляемым кодом
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати