Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
#pragma
Временно недоступен
952 / 223 / 6
Регистрация: 12.04.2009
Сообщений: 921
#1

Соптимизирует ли (любой) компилятор такой код? - C++

23.09.2012, 22:26. Просмотров 672. Ответов 11

Вопрос знатокам: нужно ли выносить за цикл создание переменной, или любой компилятор сделает оптимизацию и переменная не будет пересоздаваться? Где-то была тема как раз об этом, про фигурные скобки в С++ и области видимости, но я не смог её найти..
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 // intermediate planes 
 CVector3D intermediatePoints[4]; 
 for(int i = 0; i < intermediates; ++i) 
 { 
    float t = (i+1.0)/(intermediates+1.0); // Вот это место
 
    for(int j = 0; j < 4; ++j) 
       intermediatePoints[j] = nearPoints[j]*t + farPoints[j]*(1.0-t); 
 
 
       glBegin(GL_POLYGON); 
           glVertex3fv(&intermediatePoints[0].X); 
           glVertex3fv(&intermediatePoints[1].X); 
           glVertex3fv(&intermediatePoints[2].X); 
           glVertex3fv(&intermediatePoints[3].X); 
       glEnd(); 
 }
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
23.09.2012, 22:26
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Соптимизирует ли (любой) компилятор такой код? (C++):

Код из Memo1 - в компилятор - C++
Здравствуйте вот я написал программу и хочу чтоб при нажатии на кнопку он из Memo1 перетаскивал код в компилятор (У меня есть компилятор...

Перевести код в компилятор - C++
Нужно перевести код в компилятор, и если можно отправьте его в комментах в архиве, сейчас нет доступа к компу, а нужно срочно сдать завтра,...

Компилятор запускает предыдущий код - C++
Допустим у меня есть какой то код, скомпилировал его, потом написал другой код, сохранил все, запускаю, а компилятор запускает предыдущий...

поправьте код компилятор выдает ошибки - C++
#include &lt;iostream&gt; using namespace std; bool Hit(float x, float y, float r) { ...

Вот нашол такой код - C++
Вот нашол такой код : #include &lt;iostream&gt; // cin, out #include &lt;clocale&gt; // поддержка русского языка #include &lt;conio.h&gt; //...

Как написать такой код в си++? - C++
Здравствуйте! Как написать такой код в си++? program ch; var a,b,c:integer; begin read(a,b,c); if a &lt; b then ...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Kgfq
74 / 37 / 2
Регистрация: 23.09.2012
Сообщений: 408
23.09.2012, 22:33 #2
#pragma, 100% не знаю, но это плохой стиль - полагаться на компилер. Лучше полагаться на себя.
0
#pragma
Временно недоступен
952 / 223 / 6
Регистрация: 12.04.2009
Сообщений: 921
23.09.2012, 22:37  [ТС] #3
Цитата Сообщение от Kgfq Посмотреть сообщение
#pragma, 100% не знаю, но это плохой стиль - полагаться на компилер. Лучше полагаться на себя.
Я полностью согласен, исходники не мои, поэтому хотел спросить у знающих людей

о
Я вообще-то поиграть собирался в это http://www.wildfiregames.com/0ad/ а оказалось, что игра жутко тормозит на моей машине (вроде должна была пойти, хз), ну и стало интересно, как выглядят исходники. Там очень часто встречаются конструкции подобного рода, вот и подумал: хоть и не поиграю, так может польза какая будет с этого.
0
I.M.
564 / 547 / 5
Регистрация: 16.12.2011
Сообщений: 1,389
23.09.2012, 22:45 #4
На всяких олимпиадных задачках нам говорили, что в циклах лучше вообще переменных не создавать. Причем не важно какого типа - стандартного или своего.
Для повышения читаемости кода, напротив, рекомендуют минимизировать область видимости.
Т.е. то, как писать, зависит от того, зачем и для чего это пишется.
А вообще такие ситуации современные компиляторы разруливают достаточно успешно. И выносят за цикл все, что нужно.
1
grizlik78
Эксперт С++
1912 / 1444 / 112
Регистрация: 29.05.2011
Сообщений: 3,001
23.09.2012, 23:03 #5
С большой вероятностью накладных расходов на создание такой переменной не будет. Даже при отключённой оптимизации.
1
#pragma
Временно недоступен
952 / 223 / 6
Регистрация: 12.04.2009
Сообщений: 921
23.09.2012, 23:06  [ТС] #6
Цитата Сообщение от grizlik78 Посмотреть сообщение
С большой вероятностью накладных расходов на создание такой переменной не будет. Даже при отключённой оптимизации.
А если там повсюду такие конструкции, это что-то меняет (и ещё функция может использоваться много раз)? Видимо, без профилирования тут не обойтись..
0
grizlik78
Эксперт С++
1912 / 1444 / 112
Регистрация: 29.05.2011
Сообщений: 3,001
23.09.2012, 23:11 #7
Цитата Сообщение от #pragma Посмотреть сообщение
А если там повсюду такие конструкции, это что-то меняет?
Нет. Под автоматические переменные компиляторы обычно резервируют место в стеке ещё до начала циклов, где-то в начале функции. Причём само резервирование представляет собой одну арифметическую операцию.

Добавлено через 54 секунды
Цитата Сообщение от #pragma Посмотреть сообщение
Видимо, без профилирования тут не обойтись..
В данном случае надёжнее изучить ассемблерный листинг.
1
alex_x_x
бжни
2447 / 1652 / 84
Регистрация: 14.05.2009
Сообщений: 7,162
23.09.2012, 23:16 #8
Цитата Сообщение от #pragma Посмотреть сообщение
Видимо, без профилирования тут не обойтись..
без профилирования вообще не стоит начинать думать об оптимизации
а то превратив код в нечитаемый можно соптимизировать 5%, когда рядом будет действительно дыра
1
Evg
Эксперт CАвтор FAQ
17815 / 6025 / 388
Регистрация: 30.03.2009
Сообщений: 16,554
Записей в блоге: 26
24.09.2012, 00:13 #9
Никаких дополнительных накладных расходов на "создание" переменной внутри цикла нет. AzaKendler уже как-то задавался похожим вопросом. Там всё шло без привязки к лексическим блокам и т.п., но суть в общем-то одна и та же. Далее кидаю ссылки с моими ответами, где основная суть, ну полезно прочитать всю тему, хоть там и много букв

[C++] Взятие адреса конструктора. Физическое время существование объекта.
[C++] Взятие адреса конструктора. Физическое время существование объекта.
[C++] Взятие адреса конструктора. Физическое время существование объекта.

Добавлено через 48 минут
Кстати, по поводу локализации переменных в блоки. Возьмём пример, когда переменные объявляются вне блоков:

C
void func (void)
{
  int x, y;
  ...
  {
    /* "x" используем только в данном блоке */
  }
  ...
  {
    /* "y" используем только в данном блоке */
  }
  ...
}
В этом примере будет отведено две ячейки памяти под переменные x и y.

А если рассмотреть случай с объявлением переменных внутри блоков:

C
void func (void)
{
  ...
  {
    int x;
    ...
  }
  ...
  {
    int y;
    ...
  }
  ...
}
то в этом случае по достижении закрывающей фигурной скобки первого блока компилятор освободит ячейку памяти, отведённую под переменную "x", а по достижении открывающей фигурной скобки второго блока эту ячейку памяти переиспользует для переменной "y". Таким образом мы имеем две локальные переменные, про которые программист явно указал, что их времена жизни не пересекаются, а потому компилятор использует для них одну и ту же ячейку памяти

Однако современные компиляторы в реальности даже в первом примере для переменных "x" и "y" сумеют заиспользовать одну и ту же ячейку памяти или регистр. Потому как оптимизации в современных компиляторах довольно-таки умные. Но скорее всего будет ряд сложных случаев, когда компилятор не сумеет с этим справиться. В основном это касается случаев, когда аггрегатные переменные (массивы, структуры, классы) распределены в память. Из-за того, что при работе с полями идёт сложная работа с разными подчастями переменной, то полноценный анализ кода компилятором оказывается дорогим с точки зрения времени компиляции и потребляемой компилятором памяти. Поэтому такие анализы в компиляторах сильно упрощают.

Как итог можно сказать следующее. Если время жизни переменной реально ограничивается каким-то лексическим блоком, то переменную лучше объявить в блоке. Помимо того, что это улучшает читаемость кода, это упрощает работу компилятора, а потому в каких-то случаях (особенно после того, как сделали много inline-подстановок) это может положительно повлиять на скорость кода. Навскидку мне кажется, что для Си++ эффект будет больше, чем для Си, потому как в Си++ львиная доля библиотечной поддержки реализована в виде коротеньких шаблонных функций или inline-методов, а потому из-за массового inline код отдельно взятой процедуры становится сложным
1
#pragma
Временно недоступен
952 / 223 / 6
Регистрация: 12.04.2009
Сообщений: 921
24.09.2012, 00:17  [ТС] #10
Цитата Сообщение от Evg Посмотреть сообщение
Никаких дополнительных накладных расходов на "создание" переменной внутри цикла нет. AzaKendler уже как-то задавался похожим вопросом. Там всё шло без привязки к лексическим блокам и т.п., но суть в общем-то одна и та же. Далее кидаю ссылки с моими ответами, где основная суть, ну полезно прочитать всю тему, хоть там и много букв
Прочитал. Немного непонятно, почему накладных расходов нет, иначе зачем тогда лексические блоки, о которых ты сам и писал в той теме, где говорилось, что в С++ нет явного управления памятью для объектов. И поэтому, якобы рекомендуется ограничивать область видимости.
Ещё помню, что ты писал, что пока не закончится выполнение цикла, все эти созданные переменные висят в стеке. Жаль, не могу найти тему(

UPD: пока писал, ты написал дополнение, в-общем, примерно понятно теперь, в данном случае (переменные простые) лучше положиться на компилятор.
0
Evg
Эксперт CАвтор FAQ
17815 / 6025 / 388
Регистрация: 30.03.2009
Сообщений: 16,554
Записей в блоге: 26
24.09.2012, 09:15 #11
Цитата Сообщение от #pragma Посмотреть сообщение
иначе зачем тогда лексические блоки
Когда изобретали язык Си, в первую очередь заботились о производительности кода, а не о красоте его написания. Компиляторы в те времена были очень слабые (т.к. памяти было мало), а потому возможность ограничивать время жизни переменной диктовалось в первую очередь попытками ручных "указаний" компилятору о том, что и где можно сэкономить

Добавлено через 26 минут
Цитата Сообщение от Evg Посмотреть сообщение
Если время жизни переменной реально ограничивается каким-то лексическим блоком, то переменную лучше объявить в блоке
Но при этом надо учитывать следующее. Если мы работаем с переменной типа "класс" или "структура" в Си++, то надо учитывать, как работают конструктор и деструктор. Потому как для переменной, созданной внутри лексического блока, конструктор будет вызываться, грубо говоря, при каждом достижении открывающей фигурной скобки, а деструктор - при каждом достижении закрывающей фигурной скобки. Таким образом, если мы поместим такую переменную вовнутрь цикла из 100 итераций, то у нас 100 раз вызовется конструктор и 100 раз деструктор. Если конструктор и деструктор представляют собой inline-реализации которые тупо модифицируют значения полей (типа обнуляют или что-то ещё), то это не страшно, т.к. компилятор в процессе оптимизаций всё равно лишнее выкинет. Типа если в конструкторе обнуляли поле класса, а затем в коде в это поле мы что-то записывали, то код по обнулению поля компилятор выкинет за ненадобностью, т.к. мы всё равно после этого что-то другое записываем. Но вот если в конструкторе идёт формирование динамических массивов, а в деструкторе - их освобождение, то затаскивание переменной вовнутрь цикла может существенно программу замедлить
1
Toshkarik
1141 / 858 / 51
Регистрация: 03.08.2011
Сообщений: 2,384
Завершенные тесты: 1
24.09.2012, 09:37 #12
Как то обсуждали уже: Насколько критично обьявление переменной в теле цикла?
1
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
24.09.2012, 09:37
Привет! Вот еще темы с ответами:

Код, который ломает MSVC компилятор (просто делюсь) - C++
Привет! Иногда приходится кое-что делать под виндой и сегодня случайно наткнулся на такой креш void f(const std::string &amp;s) { ...

Компилятор оптимизировал мой код, и я не могу его отладить - C++
пишу лабу одногруппнице. задание: определить двунаправленный циклический список. элементы типа char* реализовать функции: 1. проверка...

Подскажите компилятор С++, для ассемблерных вставок на х64 код - C++
Подскажите компилятор С++ который понимает inline ассемблерные вставки на х64 код.

Не совсем понятно как работает такой код - C++
Есть консольное приложение, которое при работе выводит данные. Непонятно как работает такой код: for (;;) { char option; ...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
24.09.2012, 09:37
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru