Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.91/11: Рейтинг темы: голосов - 11, средняя оценка - 4.91
2 / 1 / 1
Регистрация: 20.09.2018
Сообщений: 17

Есть ли разница в оптимизации между определением переменной до цикла

28.09.2018, 10:27. Показов 3105. Ответов 48
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Подскажите, есть ли разница в производительности между
C++
1
2
3
4
5
6
7
8
9
int i;
while () {
    ....
    ....
    i = 0;
    while () {
          .....
    }
}
и

C++
1
2
3
4
5
6
7
8
while () {
    ....
    ....
    int i = 0;
    while () {
          .....
    }
}
Второй кусок кода с точки зрения принципа "где родился, там и пригодился" более лаконичный, но боюсь, что определение переменной отъедает доп процессорное время. Или нет?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
28.09.2018, 10:27
Ответы с готовыми решениями:

Разница между определением и объявлением переменной
Здравствуйте! При определении переменной под неё выделяется память.Скажите, выделяется ли память под переменную при объявлении без...

Разница между определением переменной до и непосредственно в самой инструкции for
Если провести инициализацию переменной до инструкции for, программа работает корректно, а если в самой инструкции то получается ошибка при...

Разница между вариантами цикла
Занимаюсь по книге Шилдт Г. - Java 8. Руководство для начинающих - 2015. Прохожу цикл FOR, был пример цикла который вычисляет целую...

48
 Аватар для Kastaneda
5232 / 3206 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
28.09.2018, 19:46
Студворк — интернет-сервис помощи студентам
Поскольку никто до сих пор не написал "расжеваный" ответ отвечу я.

По теме ТС - разницы нет. Undisputed сделал какой-то вброс ассемблерного листинга, который так и не смог объяснить. COKPOWEHEU показал дифы при разных ключах компиляции, там видно, что при некоторых оптимизациях даже в исполняемых файлах нет разницы. Там, где разница есть она заключается в следующем - при размещении переменной вне цикла ее адрес считается при каждом обращении, при размещении переменной в цикле адрес запоминается в регистре 1 раз и далее читается уже оттуда. Если говорить о скорости, то проще сказать, что разницы нет, т.к. отличие в одной микроинструкции (регистр + константа), которую ты никакими тестами не замеришь. К тому же эта разница похожа (как выразились выше) на глюки компилятора.

Не по теме:

COKPOWEHEU кстати ассемблерный листинг получается проще - ключом -S, для этого не нужно исполняемый файл дампить.



Цитата Сообщение от Undisputed Посмотреть сообщение
Во втором листинге вроде да.
На самом деле в обоих функциях ничего не выкинуто, просто в одной из функций используется трюк с lea, инструкция имеет другое предназначение, на зачастую используется для сложения нескольких операндов за одну инструкцию. Мои посты в этой теме были попыткой заставить тебя задуматься над тем, зачем ты выкладываешь ассемблерные листинги не понимая их)

Добавлено через 1 минуту
Цитата Сообщение от Undisputed Посмотреть сообщение
И как ты объяснишь существенную разницу по ссылке выше?
В variableCreatedInLoopResult data читается при кажой итерации цикла (потому что volatile), в variableCreatedNotInLoop только 1 раз до входа цикл. Отсюда такая разница.
0
 Аватар для COKPOWEHEU
4150 / 2728 / 433
Регистрация: 09.09.2017
Сообщений: 12,087
28.09.2018, 22:12
Цитата Сообщение от Kastaneda Посмотреть сообщение
COKPOWEHEU кстати ассемблерный листинг получается проще - ключом -S, для этого не нужно исполняемый файл дампить.
ключ -S не выдает отладочной информации, комментарии и соответствия ассемблерного листинга Си-шному коду.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13233 / 6865 / 1827
Регистрация: 18.10.2014
Сообщений: 17,398
29.09.2018, 00:47
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Таким образом, формально отличие есть, но слишком незначительное
GCC 8.2 -O3: https://godbolt.org/z/39Aeoe
Никаких различий вообще
0
 Аватар для avgoor
1550 / 877 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
29.09.2018, 01:02
TheCalligrapher, кстати, а сколько вариантов этого кода для различных процессоров gcc генерит? (сейчас нет под рукой). Студия генерит 3 разные точки входа.
0
30 / 21 / 8
Регистрация: 23.09.2018
Сообщений: 186
29.09.2018, 01:05
Цитата Сообщение от Undisputed Посмотреть сообщение
Вариант когда input за пределами цикла на моих тестах оказался быстрее. Можете проверить и у себя на всякий
Не смотрел код на asm, но было бы неплохо ещё сказать как компилируется код, т.к. при включении оптимизации компилятор может сделать такой же или похожий код.
0
 Аватар для COKPOWEHEU
4150 / 2728 / 433
Регистрация: 09.09.2017
Сообщений: 12,087
29.09.2018, 08:54
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Никаких различий вообще
Различия незначительные. У меня нет желания перебирать компиляторы того сайта в попытке воспроизвести результат.
Могу повторить: стандарт не гарантирует что результат компиляции будет идентичен до байта. Он не гарантирует какой из вариантов будет оптимальнее и на сколько. Попытки определить это на каком-то конкретном компиляторе дадут информацию только об этом компиляторе.
0
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
29.09.2018, 15:29
Цитата Сообщение от Kastaneda Посмотреть сообщение
На самом деле в обоих функциях ничего не выкинуто
Естественно. Иначе как процессор просчитал бы результат?
Цитата Сообщение от Kastaneda Посмотреть сообщение
В variableCreatedInLoopResult data читается при кажой итерации цикла (потому что volatile), в variableCreatedNotInLoop только 1 раз до входа цикл. Отсюда такая разница.
Ну вот. А я что говорил? Но на предыдущей странице ты заявлял обратное. Цитирую тебя:
Цитата Сообщение от Kastaneda Посмотреть сообщение
Это же очевидно, в одной из функций не производится сложения.
Что касается моей ошибки при комментировании твоего листинга: смотрел его достаточно бегло и не вникал особо в код. Это была моя ошибка.

Цитата Сообщение от Kastaneda Посмотреть сообщение
По теме ТС - разницы нет. Undisputed сделал какой-то вброс ассемблерного листинга, который так и не смог объяснить.
Что конкретно я должен был объяснить? Было заявление что разницы нет. Я выдал листинг с разницей. Не смог и не пытался это две разные вещи. Ок, если тебе нужно пояснение то я попробую пояснить более значимую разницу в первом листинге. Как ты сам заметил, в основном интересное тут то, что mov заменяется на lea. В случае когда переменная за пределами цикла используется lea, в противном случае mov.

Теперь попробуем разобраться что в данном контексте делают эти две команды.
Начнем с mov:
mov dest, src - копирует данные из src в dest. что бы скопировать данные из src в dest требуется доступ к памяти.

Теперь о lea:
Это арифметическая инструкция и в данном случае она грузит в регистр адрес данных но не сами данные. По этой причине доступ к памяти не требуется. Почему операция с доступом к памяти медленнее чем операция без доступа к памяти надеюсь рассказывать не нужно...

Цитата Сообщение от Kastaneda Посмотреть сообщение
зачем ты выкладываешь ассемблерные листинги не понимая их)
См. выше

Добавлено через 6 минут
интересно что по этому поводу скажет hoggy,
будет надменно подшучивать или все таки расскажет почему он думает что операция с доступом к памяти быстрее либо одинаково чем простое сложение без доступа к памяти?
0
 Аватар для Kastaneda
5232 / 3206 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
29.09.2018, 17:25
О каком из вариантов кода идет речь?
Цитата Сообщение от Undisputed Посмотреть сообщение
Это арифметическая инструкция и в данном случае она грузит в регистр адрес данных но не сами данные. По этой причине доступ к памяти не требуется.
В последнем примере lea совсем не для этого используется, в самом первом память все равно читается.

Добавлено через 1 час 45 минут
Цитата Сообщение от Kastaneda Посмотреть сообщение
В последнем примере lea совсем не для этого используется
Кому интересно вот, проматываем до п.3
0
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
29.09.2018, 18:33
Цитата Сообщение от Kastaneda Посмотреть сообщение
О каком из вариантов кода идет речь?
Ты вроде про первый вариант спрашивал...
Попробую расписать ход своих мыслей:
В случае с lea адрес берется путем сложения stack pointer + offset, так?
Думаю на уровне процессора даже сложения не будет потому что стек как правило фиксированного размера и адрес rsp+offset должен быть известен заранее. То есть по идее в регистр просто запишется адрес. В случае же с mov, придется копировать данные из памяти одного регистра в память другого регистра.

Все же думаю по вышеперечисленным причинам вариант с lea должен быть быстрее.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
29.09.2018, 18:33

Разница между префиксной и постфиксной формой записи счетчика цикла
Здравствуйте! Когда оформлял циклы всегда использовал такую запись: for(int i=0; i<10; i++) , которая означает что цикл...

В чем разница между объявлением переменной до и в цикле?
Как лучше? int main() { for (int i = 0; i < 10; i++) { int n = 3; out << i + n << ' '; } return 0; ...

Есть ли разница между / и \\
Есть ли разница между / и \\ ?? если к примеру попробовать получить путь к файлу для копирования и прочего..

Разница между @property и объявлением переменной в классе хедера
В чем собственно разница между обьявлением переменной в теле класса в хедере, и использовании @property и @synthesize?

Разница между this.*=*; и просто изменением переменной в методе объекта
Собственно первый вариант public void raiseSalary(int percent) { int rise=this.salary*percent/100; this.salary+=rise; } ...


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

Или воспользуйтесь поиском по форуму:
49
Ответ Создать тему
Новые блоги и статьи
Запустил конкурс "тем и промптов для текстовых квестов созданных почти чисто ИИ"
Adler 06.10.2026
Всем привет! За последние три-четыре дня я создал более 16 текстовых квестовых игр используя преимущественно по одному запросу к ИИ на игру. Мне так понравилось смотреть все ветки/ сцены во всех. . .
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru