Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.62/13: Рейтинг темы: голосов - 13, средняя оценка - 4.62
Администратор
Эксперт .NET
9602 / 4744 / 761
Регистрация: 17.04.2012
Сообщений: 9,592
Записей в блоге: 14
1

Оптимизации, производимые компилятором

01.09.2013, 14:01. Показов 2453. Ответов 24
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Цитата Сообщение от Dzhej-Dzhej Посмотреть сообщение
.net-языки не предназначены для быстродействия
Это не значит, что на них можно писать только медленный код. Джеффри Рихтер утверждает, что управляемый код может работать быстрее неуправляемого при сходных алгоритмах - за счёт оптимизации на лету.

NickoTin: сообщения выделены из темы Ускоренное сложение строк
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
01.09.2013, 14:01
Ответы с готовыми решениями:

Помощь с компилятором.
Понял как компилировать, все делается , но когда компилит , то при запуске тупо встает cmd и ничего...

Выбор редактора C# с компилятором
Просто хочу изучать C#, нужно выбрать редактор с встроенным компилятором,но Visual Studio не...

Не могу разобратся с компилятором((
Не могу понять как его вызвать. В книге написано запустите компилятор csc.exe Нашел у себя в папке...

Как пользовать компилятором
Привет всем. Появился такой вопрос: "Можно ли компилировать программу, но чтоб после компиляции...

24
Master of Orion
Эксперт .NET
6098 / 4954 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
01.09.2013, 14:31 2
tezaurismosis, кстати в итоге кроме инлайна некоторых строк и массивов особо этих оптимизаций не видно. Даже функции не инлайнятся. Хотя существуют компиляторы, которые на лету часто вызываемый код оптимизируют еще сильнее и заменяют исходный сгенерированный код на оптимизированный... А в .Net этого нету
0
Администратор
Эксперт .NET
9602 / 4744 / 761
Регистрация: 17.04.2012
Сообщений: 9,592
Записей в блоге: 14
01.09.2013, 15:20  [ТС] 3
Цитата Сообщение от Psilon Посмотреть сообщение
кроме инлайна некоторых строк и массивов особо этих оптимизаций не видно
Код на C# -(1)-> Код на IL -(2)-> Код на машинном языке
1) Вот здесь инлайн строк
2) Оптимизация для конкретной архитектуры - более эффективное использование машинных команд и др.
По крайней мере, так говорят Майкрософт и Джеффри Рихтер. В чём именно заключается пункт 2 я сказать не могу.
В 2007 году, когда ещё была при жизни Managed DirectX, те же Майкрософтовцы в документации приписывали проигрыш в 25% производительности (по большей части по FPS) коду на C# в сравнении с неуправляемым кодом на C++
0
2835 / 1644 / 254
Регистрация: 03.12.2007
Сообщений: 4,222
01.09.2013, 15:31 4
Цитата Сообщение от tezaurismosis Посмотреть сообщение
2) Оптимизация для конкретной архитектуры - более эффективное использование машинных команд и др.
По крайней мере, так говорят Майкрософт и Джеффри Рихтер. В чём именно заключается пункт 2 я сказать не могу.
Думаю, например, использование инструкций SSE для математики, если они поддерживаются. Конечно, при необходимости можно сделать несколько вариантов одной функции под различные процессоры и выбирать при запуске программы. При jit компиляции же это происходит естественным образом.
0
Эксперт .NET
17685 / 12871 / 3365
Регистрация: 17.09.2011
Сообщений: 21,136
01.09.2013, 15:33 5
Цитата Сообщение от Dzhej-Dzhej Посмотреть сообщение
код компилируется на этапе исполнения
Код можно скомпилировать на этапе установки приложения на клиентской системе.
0
Master of Orion
Эксперт .NET
6098 / 4954 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
01.09.2013, 15:35 6
tezaurismosis, ну например инлайна методов нету. Хотя бы в пределах видимости класса. Нету оптимизации алгоритма, если он один раз сгенерировался, этот код уже потом не будет наменяться на более оптимальный. И тд
0
Эксперт .NET
17685 / 12871 / 3365
Регистрация: 17.09.2011
Сообщений: 21,136
01.09.2013, 15:43 7
Цитата Сообщение от Psilon Посмотреть сообщение
например инлайна методов нету
В .NET 4.5 вроде же как добавили инлайны?

Цитата Сообщение от Psilon Посмотреть сообщение
Нету оптимизации алгоритма, если он один раз сгенерировался, этот код уже потом не будет наменяться на более оптимальный.
А зачем его снова оптимизировать, если это уже сделано при генерировании?
Или JIT первый раз не до конца оптимизирует?
0
Master of Orion
Эксперт .NET
6098 / 4954 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
01.09.2013, 15:50 8
kolorotur, ну например после 100 прогонов выяснилось, что в метод в 90% случаев передается значение A. Тогда если мы закэшируем возвращаемое значение для А мы получим 10х прирост производительности.

Добавлено через 2 минуты
Или например, что у нас есть
C#
1
if (a > 0 && b >0 && c > 0 && d > 0)
, при этом нам стало известно, что d>0 выполняется очень редко, то можно преобразовать к такому виду:
C#
1
if (d > 0 && a > 0 && b >0 && c > 0  )
теперь он проверяется первым и не производит лишних сравнений. НУ и т.д. По-моему у Java или у кого-то еще есть подобный оптимизирующий компилятор, который на основе собираемой статистики оптимизирует код, но название забыл.
1
Эксперт .NET
17685 / 12871 / 3365
Регистрация: 17.09.2011
Сообщений: 21,136
01.09.2013, 16:15 9
Psilon, а, вон о чем речь.
Это называется "рантайм берет на себя работу программиста, который не соизволил прогнать свой код через профайлер перед тем, как делать коммит". Даже и не знаю, хорошо это или плохо.

МС, насколько мне известно, в этом плане старается по максимум придерживаться политики невмешательства: если прогер наваял пахнущий код с условиями вроде if (ConnectToDatabase() && QueryServer() && WriteToFile() && i > 0), то это проблемы прогера и его начальника, а не рантайма.
В этом плане я придерживаюсь того же мнения.

Цитата Сообщение от Psilon Посмотреть сообщение
например после 100 прогонов выяснилось, что в метод в 90% случаев передается значение A.
Я понимаю, что это всего лишь пример, но вот стало интересно: если бы оптимизатор действительно кэшировал возвращаемое значение функции, то как бы он в этих 10-и процентах вызовов определял, что значение в этот раз вернется другое и кэш надо бы обновить?
0
Master of Orion
Эксперт .NET
6098 / 4954 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
01.09.2013, 16:29 10
Psilon, а, вон о чем речь.
Это называется "рантайм берет на себя работу программиста, который не соизволил прогнать свой код через профайлер перед тем, как делать коммит". Даже и не знаю, хорошо это или плохо.
То есть вы всегда знаете, когда распространяете приложение, какие данные будет забивать пользователь?

Кстати насчет:
Или JIT первый раз не до конца оптимизирует?
конечно не до конца. Компиляция проекта на C++ у некоторых товарищей занимает по 10 часов (особенно с использованием буста и пр), а JIT должен предоставить код буквально за несколько миллисекунд. У него тупо нету времени проанализировать весь код. А если мы будем собирать сразу на машине с помощью ngen, то теряем все плюсы от "учитывания непосредственной платформы пользователя".

Добавлено через 5 минут
Пример: возьмем такой код:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
using System;
 
namespace ConsoleApplication132
{
    class Program
    {
        static void Main(string[] args)
        {
            int sum = 0;
            for (int i = 0; i < 100; i++)
            {
                sum += Get4();
            }
            Console.WriteLine(sum);
            Console.ReadKey();
        }
 
        private static int Get4()
        {
            return 4;
        }
    }
}
я считаю, что оптимизатор должен его привести к такому виду:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
using System;
 
namespace ConsoleApplication132
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(400);
            Console.ReadKey();
        }
    }
}
Однако если мы декомпильнем исходник (release, все как надо), то мы увидим..
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// Type: ConsoleApplication132.Program
// Assembly: ConsoleApplication132, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
// Assembly location: D:\Projects\ConsoleApplication132\ConsoleApplication132\bin\Release\ConsoleApplication132.exe
 
using System;
 
namespace ConsoleApplication132
{
  internal class Program
  {
    private static void Main(string[] args)
    {
      int num = 0;
      for (int index = 0; index < 100; ++index)
        num += Program.Get4();
      Console.WriteLine(num);
      Console.ReadKey();
    }
 
    private static int Get4()
    {
      return 4;
    }
  }
}
он даже не заинлайнил функцию, возвращающую константу... О чем тут можно говорить
0
Почетный модератор
Эксперт .NET
8721 / 3673 / 404
Регистрация: 14.06.2010
Сообщений: 4,513
Записей в блоге: 9
01.09.2013, 17:35 11
Цитата Сообщение от Psilon Посмотреть сообщение
Однако если мы декомпильнем исходник (release, все как надо), то мы увидим
Смотреть нужно код сгенерированный JIT'ом, а он будет таким:
Для x86
C#
1
for(int i = 0; i < 100; ++i) sum+=4;
Assembler
1
2
3
4
5
00390059 33c0            xor     eax,eax   ; i = 0
0039005b 83c604          add     esi,4     ; sum += 4
0039005e 40              inc     eax       ; i++
0039005f 83f864          cmp     eax,64h   ;
00390062 7cf7            jl      0039005b  ; i < 100 goto 0039005b
Для x64:
C#
1
for(int i = 0; i < 100; i+=4) sum+=16; // Уменьшено число итераций
Assembler
1
2
3
4
5
000007fe`8d7b00a0 8bd9            mov     ebx,ecx           ; в конечном счёте 400 будет в ebx
000007fe`8d7b00a2 83c110          add     ecx,10h           ; sum+=16
000007fe`8d7b00a5 83c004          add     eax,4             ; i+=4
000007fe`8d7b00a8 83f864          cmp     eax,64h           ;
000007fe`8d7b00ab 7cf3            jl      000007fe`8d7b00a0 ; i < 100 goto 000007fe`8d7b00a0
Соглашусь что можно было бы еще оптимизировать, почему именно так сгенерировано точно сказать не могу, но предположу что оптимизация должна быть такой чтобы алгоритм не менялся.
2
Master of Orion
Эксперт .NET
6098 / 4954 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
01.09.2013, 19:43 12
NickoTin, согласен, что смотреть надо x86, но я считаю, что все функции возвращающие константы должны инлайниться. Ведь
C#
1
const int x = 1 << 32/5 + 2;
можно спокойно написать и он его посчитает на этапе компиляции. Так почему же он не может увидеть, что в цикле одни константы? Риторические вопросы, но не так уж сложно его обучить видеть константы за пределами простых арифметических операций.

Добавлено через 2 минуты
Я и говорю. Если бы на основе статистики он бы обнаружил (пусть бы в первый раз так сгенерировал, ладно), что в этом цикле все время одно и то же значение получается, то он бы запустил более глубокую проверку, обнаружил бы, что там действительно константа (а не просто такое совпадение, что 1000 раз вернулось одно значение, а на 1001 может вернуться другое) и перекомпилировал уже сгенерированный exe.

Добавлено через 35 минут
Кстати а вот что выдал Сшный аналог:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
 
 
inline int Get4()
{
    return 4;
}
 
 
int main()
{
    int sum = 0;
    for (int i = 0; i < 100; i++)
    {
        sum += Get4();
    }
    printf_s("%i", sum);
    getchar();
    return 0;
}
ассемблер
Assembler
1
2
3
4
_main proc near 
push    190h  ; 400!
push    offset aI       ; "%i"
call    ds:__imp__printf_s
Добавлено через 7 минут

Не по теме:

Все-таки я очень люблю С, в отличие от С++. Он простой, понятный, элегантный... Иногда даже больше шарпа:)



Добавлено через 55 секунд
Кстати забавно, что ASM кода меньше, чем "высокоуровневого"

Добавлено через 6 минут
NickoTin, кстати а куда он компилирует бинарник? Не нашел
3
Администратор
Эксперт .NET
9602 / 4744 / 761
Регистрация: 17.04.2012
Сообщений: 9,592
Записей в блоге: 14
01.09.2013, 19:50  [ТС] 13
Psilon, удивительно, но даже если убрать inline от Get4, оптимизация остаётся (я нрассчитывал на иной результат)
Код получен в дизассемблере Visual Studio 2012 в конфигурации Release
Assembler
1
2
3
4
 push        190h  
 push        0BE2100h  
 call        dword ptr ds:[00BE2094h]  
 add         esp,8
0
Master of Orion
Эксперт .NET
6098 / 4954 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
01.09.2013, 19:51 14
tezaurismosis, вот-вот и я о том же...
0
Почетный модератор
Эксперт .NET
8721 / 3673 / 404
Регистрация: 14.06.2010
Сообщений: 4,513
Записей в блоге: 9
01.09.2013, 22:12 15
Цитата Сообщение от Psilon Посмотреть сообщение
все функции возвращающие константы должны инлайниться
Ну так с ними это и происходит во время работы JIT'а, а инлайниться в IL код не должны, потому что в .NET есть такая вещь как рефлексия и решения построенные с её использованием будут рушиться в таком случае.
Цитата Сообщение от Psilon Посмотреть сообщение
NickoTin, кстати а куда он компилирует бинарник? Не нашел
Не понял какой бинарник?

Добавлено через 2 минуты
Цитата Сообщение от tezaurismosis Посмотреть сообщение
убрать inline от Get4, оптимизация остаётся
Компилятор C/C++ от MS не делает акцент на inline, он может его учесть или нет в зависимости от ситуации где код используется и там где от этого инлайна действительно можно получить выгоду. Чтобы указать компилятору что функцию нужно заинлайнить используется ключевое слово __forceinline.
1
Master of Orion
Эксперт .NET
6098 / 4954 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
01.09.2013, 22:13 16
Цитата Сообщение от NickoTin Посмотреть сообщение
Ну так с ними это и происходит во время работы JIT'а, а инлайниться в IL код не должны, потому что в .NET есть такая вещь как рефлексия и решения построенные с её использованием будут рушиться в таком случае.
ты же сам декомпильнул и получил, что он (JIT) никуда не оптимизировал ничего. Тут рефлексия не при чем.
Не понял какой бинарник?
куда JIT кладет то, что он скомпилировал из IL ?
0
Почетный модератор
Эксперт .NET
8721 / 3673 / 404
Регистрация: 14.06.2010
Сообщений: 4,513
Записей в блоге: 9
01.09.2013, 22:21 17
Цитата Сообщение от Psilon Посмотреть сообщение
что он (JIT) никуда не оптимизировал ничего
Вызов метода Get4 был убран и взамен него была подставлена 4, метод Get4 даже не был отдан JIT'у на съедение. Чем не оптимизация?
Цитата Сообщение от Psilon Посмотреть сообщение
Тут рефлексия не при чем
Именно в этом случае да, но в общем случае компилятор не имеет право убирать методы которые явно не используются, т.к. они могут вызываться неявно.
Цитата Сообщение от Psilon Посмотреть сообщение
куда JIT кладет то, что он скомпилировал из IL ?
Ммм, никуда не кладёт, JIT работает с памятью, образно, ему на вход подается массив байт представляющих собой IL код, он этот поток обрабатывает и генерирует по нему ASM код под конкретную архитектуру. Вот статья хорошая на эту тему от Daniel Pistelli: http://www.ntcore.com/files/netint_native.htm
Цитата Сообщение от Psilon Посмотреть сообщение
ты же сам декомпильнул
и я ничего не декомпилировал, это всё из под отладчика (WinDbg), работу JIT'а можно только так просмотреть.
0
Master of Orion
Эксперт .NET
6098 / 4954 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
01.09.2013, 23:38 18
NickoTin, сколько раз встречал, что JIT компилирует один раз, а потом просто исполняет скомпилированный код. Где-то он его хранит в итоге...
Вызов метода Get4 был убран и взамен него была подставлена 4, метод Get4 даже не был отдан JIT'у на съедение. Чем не оптимизация?
С-шный код намного лучше оптимизирован. Экспоненциально я бы сказал. Вместо O(N) стало O(1)

Именно в этом случае да, но в общем случае компилятор не имеет право убирать методы которые явно не используются, т.к. они могут вызываться неявно.
он может заинлайнить, но не удалять сам метод.
0
Почетный модератор
Эксперт .NET
8721 / 3673 / 404
Регистрация: 14.06.2010
Сообщений: 4,513
Записей в блоге: 9
02.09.2013, 00:29 19
Цитата Сообщение от Ps[quote="Psilon Посмотреть сообщение
сколько раз встречал, что JIT компилирует один раз, а потом просто исполняет скомпилированный код. Где-то он его хранит в итоге
JIT компилирует по мере необходимости/использования, скомпилированный метод располагается в памяти. Сначала загрузчик во время загрузки и инициализации типа создает заглушку для методов, когда метод вызывается первый раз эта заглушка передает управление JIT'у который компилирует метод, тем самым последующие вызовы метода будут происходить уже без участия JIT'а, заглушка заменяется на вызов скомпилированного метода. Официальное описание: http://msdn.microsoft.com/en-u... 32s8a.aspx , раздел Compilation by the JIT Compiler.
Цитата Сообщение от Psilon Посмотреть сообщение
С-шный код намного лучше оптимизирован. Экспоненциально я бы сказал
Я очень за это рад Пытайтесь пробиться в MS, в команду разработчиков JIT компилятора и производите оптимизацию алгоритмов генерации конечного кода, уверен, все Вам скажут огромнейшее спасибо если Вы добьетесь такой же оптимизации как это делает компилятор C, только стоит учесть хотя-бы несколько маленьких факторов: C компилятор - статический, JIT-же динамический, т.е. нужно будет предусмотреть множество факторов которые должны учитываться для конкретной платформы во время исполнения.
Цитата Сообщение от Psilon Посмотреть сообщение
он может заинлайнить, но не удалять сам метод.
Не пропускайте пожалуйста строки в моих сообщениях, я уже 2 раза писал о том что метод Get4 заинлайнен, взамен вызова подставляется 4.
1
Master of Orion
Эксперт .NET
6098 / 4954 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
02.09.2013, 00:34 20
NickoTin,
Я очень за это рад Пытайтесь пробиться в MS, в команду разработчиков JIT компилятора и производите оптимизацию алгоритмов генерации конечного кода, уверен, все Вам скажут огромнейшее спасибо если Вы добьетесь такой же оптимизации как это делает компилятор C, только стоит учесть хотя-бы несколько маленьких факторов: C компилятор - статический, JIT-же динамический, т.е. нужно будет предусмотреть множество факторов которые должны учитываться для конкретной платформы во время исполнения.
Если бы...
http://habrahabr.ru/post/183130/
0
02.09.2013, 00:34
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
02.09.2013, 00:34
Помогаю со студенческими работами здесь

Анонимный тип - это генерация компилятором
A) Структуры, состоящей из свойств B) Класса, состоящего из полей C) Структуры, состоящей из...

Как пользоваться компилятором командной строки csc.exe?
Сегодня только начала учить С# по книге Г.Шилдта . И столкнулась с проблемой запуска элементарной...

Как можно посмотреть код, генерируемый компилятором, для итераторов
как можно посмотреть этот сгенерированный код?

Непонятки с компилятором
Есть код, выполняется правильно bool onCreateNode = true; foreach(Node item in Parent.Elements)...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru