|
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
|
|||||||||||
Почему в данном случае работа с заранее выделенной памятью медленнее чем с динамической?12.12.2016, 18:47. Показов 2284. Ответов 38
Метки нет (Все метки)
Написал функцию которая на основе списка выделяет память и при каждом вызове возвращает указатель на следующий элемент для объекта.
Код где используется заранее выделенная память обернул в std::chrono::nanoseconds, что бы получить время исполнения с помощью вычисления разности ДО и ПОСЛЕ выполнения. Вариант с заранее выделенной памятью почему то оказался медленнее Вариант с заранее выделенной памятью (результат: http://rextester.com/FNDGT52360) под спойлером так же есть код Кликните здесь для просмотра всего текста
Вариант без использования заранее выделенной памяти и placement new http://rextester.com/FVC18352 Кликните здесь для просмотра всего текста
Почему так происходит? Вроде бы выриант с заранее выделенной памятью должен быть быстрее, а здесь наоборот Хуже того, если функцию getPtr объявить как inline, то работает ещё медленнее Добавлено через 1 час 9 минут Проверил одну версию. Подумал тормоза возникают из за того что первый вызов функции, который приводит к инициализации списка находится в цикле. Вынес его из цикла, так ещё медленнее стало! В функции getPtr вывел запись Initialized что бы убедиться в том, что инициализация происходит всего один раз. http://rextester.com/DOS20329 Откуда эти тормоза? Ведь по при вызове функции переставляется указатель на следующий свободный элемент и возвращается указатель на текущий свободный элемент списка и подставляется в placement new
0
|
|||||||||||
| 12.12.2016, 18:47 | |
|
Ответы с готовыми решениями:
38
|
|
503 / 352 / 94
Регистрация: 22.03.2011
Сообщений: 1,112
|
|
| 12.12.2016, 20:01 | |
|
Причин может быть много, начиная от банальной оптимизации - выкидывание цикла который ничего не делает. Дизассемблируте код смотрите что оставил Вам компилятор.
П.С. Ну и вынесите аллокацию за цикл. Добавлено через 6 минут Ну и почитайте что такое ПУЛ памяти. Ибо у Вас выдиление идет через постоянной нью Добавлено через 2 минуты П.С.С. Ну и почитайте что тако спискок и как он организован.
0
|
|
|
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
|
|||||
| 12.12.2016, 20:05 [ТС] | |||||
![]()
0
|
|||||
|
503 / 352 / 94
Регистрация: 22.03.2011
Сообщений: 1,112
|
|||||||||||
| 12.12.2016, 20:15 | |||||||||||
Я Вам оставил коменты. И ссылку на вики что такое лист https://en.wikipedia.org/wiki/Linked_list Добавлено через 3 минуты
1
|
|||||||||||
|
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
|
||
| 12.12.2016, 20:35 [ТС] | ||
|
Изначально выделяется память для каждого элемента списка и его указатель записывается в next Далее эти указатели используются один за другим
0
|
||
|
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
|
|||
| 12.12.2016, 20:37 | |||
|
Для начала нужно исправить грубейшие ошибки при работе с памятью, которые порождают UB. Если в программе есть UB, то никакими метриками ее оценивать нельзя, т.к. все они заведомо могут быть скомпрометированы. Добавлено через 1 минуту
1
|
|||
|
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
|
|
| 12.12.2016, 20:39 [ТС] | |
|
0
|
|
|
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
|
|||
| 12.12.2016, 20:42 | |||
|
Добавлено через 2 минуты Вот, сохранил твою идею: http://rextester.com/OGAH34638
0
|
|||
|
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
|
|||
| 12.12.2016, 20:56 [ТС] | |||
|
0
|
|||
|
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
|
|||
| 12.12.2016, 21:02 | |||
Сообщение было отмечено Undisputed как решение
РешениеВариант без пула дает в среднем 36 ns на аллокацию: http://rextester.com/EEDX84367 Вариант с пулом, в среднем 4 ns: http://rextester.com/UQQPD30215
1
|
|||
|
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
|
||
| 12.12.2016, 21:17 [ТС] | ||
|
В цикле для каждого next-а который является указателем выделяется память с помощью new char, равная размеру объекта. В итоге получаем указатель который указывает на область размером sizeof(Test) Далее по необходимости указатели возвращаются один за другим Разве тут есть ошибка?
0
|
||
|
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
|
||
| 12.12.2016, 21:20 | ||
|
Указатель у тебя находится "внутри" области памяти, которую ты выделил (смотрим на reinterpret_cast). В итоге этот указатель потом будет перетёрт объектом Test. Зачем нужна такая структура данных, которая сама себя уничтожает?
0
|
||
|
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
|
||
| 12.12.2016, 21:27 [ТС] | ||
|
Наверное туплю, но не могу понять.
0
|
||
|
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
|
|||
| 12.12.2016, 21:35 | |||
|
Потом взял и наглым образом сказал, что этот массив является структурой list. Внутри которой находится указатель next. Далее что ты делаешь? Записываешь в этот указатель адрес следующего элемента. Потом что ты делаешь? Возвращаешь очередной list в качестве памяти свободной для размещения. Итого у тебя действительно есть память, пригодная для размещения объекта Test, но указатель next, который был там записан теперь безвозвратно утерян. Одноразовая структура получилась, ничего больше сделать с ней нельзя, например если ты захочешь вернуть элемент списка обратно в пул, то ты не сможешь это сделать, т.к. его адресация утеряна. Добавлено через 2 минуты Итого у тебя элемент списка - это одновременно и память и структура данных для организации этой памяти. Но так не бывает. Ты или едешь, или шашечки ждешь.
1
|
|||
|
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
|
||||
| 12.12.2016, 21:46 [ТС] | ||||
|
Добавлено через 5 минут
0
|
||||
|
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
|
|||
| 12.12.2016, 21:50 | |||
|
Добавлено через 1 минуту ![]() В общем, твоя схема с перезаписью будет работать, но то, что ты пишешь в процитированном, демонстрирует непонимание о чем я писал выше ![]() Такие дела.
1
|
|||
|
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
|
|||
| 12.12.2016, 21:54 [ТС] | |||
![]() )) Алгоритм вроде рабочий ![]() Но в чем ошибка была в моем коде кроме отсутствия квадратных скобок не догнал... я сейчас очень тупой, попробую завтра с утра глянуть твой код
0
|
|||
|
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
|
|||
| 12.12.2016, 22:14 | |||
|
Вот пишешь ты: Вопрос, естественно, риторический.Но схема и правда рабочая, безотносительно твоих "непоняток". Это шаманизм в чистом виде: ты сделал что-то более-менее рабочее, но того как оно на самом деле работает до конца не понял ![]() Вот твоя схема, работает, при желании: http://rextester.com/XGS73196 Проблема объектов, меньших, чем sizeof(void*), тут, кстати, решена.
1
|
|||
|
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
|
|||
| 12.12.2016, 22:32 [ТС] | |||
Я могу ошибаться в силу того что ещё совсем-совсем зеленый, недалекий Плюсы сложная штука... Сейчас попробую рассказать как я это себе представляюНасколько я понимаю, само выражение struct {...} это просто языковая конструкция, а память требуется для хранения её полей, ведь так? Когда мы пишем list *next то говорим, что там будет находится указатель. То есть после описания структуры ещё никакой указатель никуда не указывает. В процессе выделения памяти заранее, мы выделяем память char[] и делаем каст, что бы успешно присвоить его next-у. Именно тогда next начинает уже указывать в конкретную область, но так как next это указатель который пришел от new, от находится отдельно от данных.
0
|
|||
|
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
|
||||||||||||
| 12.12.2016, 22:53 | ||||||||||||
|
sys_beginner, плаваешь около истины, но еще не до конца. Нужен рисунок:
Ты выделил sizeof(Test) байт, затем скастил указатель на них к list *. list (sizeof(list) == sizeof(list*)) у нас занимает меньше, чем Test, поэтому реально использоваться из 8 байт (sizeof(Test) == 8) будут только 4 (условимся, что у нас 32-битная платформа). Теперь перейдем ко второй итерации, head у нас уже есть, и он указывает на прежде выделенные 8 байт, первые 4 байта из которых притворяются list`ом. Настала пора присвоить next`у head-элемента полученный на второй итерации указатель (тоже, предварительно скастованный к list`у). Внимание вопрос: где будет располагаться этот адрес? Правильно в первых 4х байтах нашего буфера, который прячется за head указателем.
При записи туда объекта через placement new, естественно, этот адрес будет перезаписан. Ну это ты уже понимаешь, надеюсь, раз предложил выход из ситуации. Собственно, об этом простом факте и была моя куча текста сверху... Добавлено через 4 минуты ![]() Т.е. отдельно от данных у тебя находится только самый-самый первый указатель, который в твоей реализации сидит в static области памяти. Все остальные next`ы используют ту область памяти, которую предполагается использовать под данные и будут утеряны при конструировании там объекта. Опять-таки, речь велась только об этом.
1
|
||||||||||||
| 12.12.2016, 22:53 | |
|
Помогаю со студенческими работами здесь
20
Работа с динамической памятью Работа с динамической памятью! работа с динамической памятью Работа с динамической памятью. Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
|
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11
— это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
|
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11
Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
|
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
|
|
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/
O1rJuneU_ls
https:/ / vkvideo. ru/ video-115721503_456239114
|
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ВВЕДЕНИЕ
Введу сокращения:
аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
|
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi
ветка по-частям.
коммит Create переделка под биомассу. txt
вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
|
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ *
Дана цепь постоянного тока с сопротивлениями и источниками (напряжения, ЭДС и тока). Найти токи и напряжения во
всех элементах. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и. . .
|