2082 / 1573 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
|
|||||||||||||||||
1 | |||||||||||||||||
О деталях и возможностях реализации <vector>06.04.2016, 04:17. Показов 2572. Ответов 82
Метки нет (Все метки)
Ну это уже в зависимости от зависимости. Примерно в 50% случаев внутренняя проверка только дает оверхед. из кода AnsiString (той которая в комплекте C++ Builder)
в подавляющем большинстве случаев разумно вот так:
0
|
06.04.2016, 04:17 | |
Ответы с готовыми решениями:
82
О возможностях реализации поставленных задач Скрыть <iostream> в деталях реализации Программа для реализации арифметических операций Matrix, Vector Написать шаблон класса на основе класса vector для реализации стековой структуры данных |
2082 / 1573 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
|
|
07.04.2016, 03:34 [ТС] | 21 |
Если код не в состоянии вычислять границы массивов к которым он обращается он не то что неотказоустойчивый, он нерабочий. Екскепшены в этом плане предоставляют огромные удобства по вылову таких ошибок. А вот когда он надежно вычисляет границы извне, то и никакие внутренние проверки становятся не нужны.
В том числе по всем вышестоящим функциям? Добавлено через 4 минуты Проверять надо что пользователь в консольке вводит. А еще лучше не в консольке давать индексы элементов указывать а мышкой выбирать из существующих. И вызывать его на каждом шагу? Я свойство Capacity для себя как то не закрывал. Но с GrowStep достаточно один раз указать шаг, при потребности рост с таким резервом. Добавлено через 2 минуты В моем случае в бою она не нужна. Потому что в учении добились что такая пакость у супостата не пройдет. Добавлено через 2 минуты Кто запрещает пользоваться теми же методами для дебага если они удобны? Добавлено через 1 минуту В этом случае throw используется фактически как return через несколько уровней вложенности вызовов, именно в то место где ждут результат. Тоже удобное применение. Но не единственное.
0
|
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
|
|
07.04.2016, 03:54 | 22 |
Если "один раз указать шаг", будет квадратичная сложность алгоритма вставки N элементов. На N вставок n/GrowStep реаллоков, каждый следующий тормозит на GrowStep единиц времени больше (потому что весь массив перемещается в новое место). То есть, суммарные тормоза - сумма арифметической прогрессии, растущая пропорционально квадрату N.
Так я еще раз повторяю, константное амортизированное (суммарное время пиханий/число пиханий) время ваш велосипед гарантирует? В состоянии. Просто, стандартная реакция на некорректные входные данные - аварийное завершение алгоритма и цепочка return до обработчика ошибок. Так какая собственно, разница из какого места эта цепочка начнется? М... Вы отладчиком пользоваться пробовали? Да, он покажет весь стек вышестоящих функций. Если же предлагается запускать дебаг-сборку на удаленной машине без отладчика, так это сексуальное извращение.
0
|
2082 / 1573 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
|
|
07.04.2016, 05:55 [ТС] | 23 |
Правильно. Вот по trow он и останавливается на сбойной итерации. Переходишь вверх по стеку вызовов и смотришь значения всех переменных при которых произошел сбой. А не трассируешь до посинения. Фактически используется как debug echo с автоматически установленной на него точкой останова.
Размер шага при этом может очень даже зависеть от количества вставок за один присест, и указываться для каждого конкретного массива в любое время. При этом на малых последовательностях только одно распределение, а при стратегии вектора именно на малых последовательностях будет постоянный реалок с копированием. При большом количестве таких малых последовательностей тормоза у std::vector гарантированы если через reserve не имитировать GrowStep. На больших же последовательностях std::vector будет оверхед по памяти, причем чем больше последовательность тем этот оверхед выше. Управление размером роста такая штука что не угадаешь на все случаи жизни как размер прироста делать. А тем более если еще и при удалении автоматически размер уменьшать. Для более-менее универсальной стратегии подходит только страничное распределение, но и оно только при очень интенсивных добавлениях/удалениях в/из начало/конец последовательности оправдано, иначе будет сравнимо с умным использованием Capacity и GrowStep. Опять же учитывая что в подавляющем большинстве случаев сами динамические массивы хранят списки указателей на объекты то копируется при ресайзе не такой уж и большой объем данных. Ну а при рандомной вставке/удалении все равно не сравнимо со временем затрачиваемым на сдвиг последовательности, мало того сдвиг может быть совмещен с копированием при ресайзе. Добавлено через 3 минуты Если код сгенерировал некорректные входные данные для нижестоящего кода, то это нерабочий код. Добавлено через 19 минут Начнем с того зачем и как его использовать и зачем он нужен решать только мне в каждом конкретном случае, а не какому то комитету или еще кому то. К примеру как то использовал exception для возврата результата из рекурсивной функции поиска. И все прекрасно.
0
|
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
|
||||||
07.04.2016, 06:06 | 24 | |||||
По throw он вообще не останавливается. Исключение прилетает в catch секцию, catch секция плюется сообщением "извините, не взлетело. Причина - error.what()" и программа пашет дальше. Или настоящие индейцы обработчики исключений не пишут?
Вы определитесь - мы указываем шаг "в любое время" или один раз? И мы что оптимизируем, среднее время вставки или время вставки в небольшие массивы? Потому как второе делается совсем иначе.
0
|
2082 / 1573 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
|
|
07.04.2016, 07:04 [ТС] | 25 |
Не пробовали по другому вопрос ставить - stl не осилила мои потребности ни к контейнерам, ни к делегатам,ни к свойствам, ни к RTTI. Ну слава богу руки вроде не кривые чтобы своими контейнерами обзавестись и в случае необходимости расширять номенклатуру оных, ну а на все остальное борланд есть, да и контейнеры у борланда тоже очень даже ничего, массивы конечно не совсем айс, вынужденный аналог паскалевских, но вот строки и списки это нечто. НУ а двумерные и т.д. массивы по оперделению свои. Их ни в одном комплекте нет.
P.S.: да кстати, похоже STL вообще ничьи потребности не осилила, потому как не встречал использования оной ни в коде от Борланда (хотя на борту лежит в версии Dinkumware), ни в коде от Майкрософт (хотя на борту в своей патентованной версии, работающей местами через расширения синтаксиса), ну если где то и проскакивает у мелкомягких, то по мелочи на задворках. А вся основная работа работается лисапетами как вы их называете. Добавлено через 1 минуту Вот в том то и дело что нельзя оптимизировать все и сразу. Добавлено через 32 минуты "Обалденный" способ. Особенно счастливы от него будут те кому при помощи этих векторов нужно будет организовывать связность деревьев, у которых в любой момент времени у подавляющего большинства элементов эти вектора нижестоящих узлов пустые. Добавлено через 6 минут Ну ежели в хеллоувердах то может и так. А ежели в софте то как бы может в ответ не диагностическим сообщением плюнуть а к примеру сотней тонн жидкой стали. Добавлено через 8 минут P.S.: про оптимизацию я это к тому что на все случаи жизни не угадаешь, поелику оптимизация по одному признаку, нужная в одном конкретном случае зачатую противоречит оптимизации нужной в другом конкретном случае. Поэтому что бы там коммитет в плане какой либо библиотеки не пытался стандартизировать, лисапетили и лисапетить будут, и правильно делают. А те кто это еще неосилили и есть неосилянты. Добавлено через 9 минут А разве надпрограмма не является пользователем подпрограммы? Вот ее ошибки светятся и штатным образом дебагятся при помощи екскепшинов. Ну а если так смотреть, то два наиболее эффективных способы отладки это трассировка с точками останова и debug echo. И сколько не холиварили на тему что из этих спсобов лучше, то и тот и тот имеет свои как огромные плюсы так и нехватку плюсов второго способа. А соостветсвенно те кто при мозгах всегда пытались два эти способа комбинировать, с самой зари компьютерных технологий. Так вот throw это по большому счету кроме всего остального еще и debug echo с автоматически установленной на него под дебаггером точкой останова - т.е. мощнейший инструмент отладки о котором мечтали во все времена. И не использовать его просто глупо.
0
|
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
|
|
07.04.2016, 07:13 | 26 |
Таки да, будут счастливы. Потому как выделение динамической памяти под эти вектора скушает тактов этак сто, а то и всю тысячу. И за это время можно десять раз завершить инициализацию собственно узла дерева. В Виларибо уже праздник, а жители Вилабаджо все еще ждут завершения выделения памяти под вектор.
Вы определитесь, вам экономию памяти или быструю работу? Потому как и то, и то разом не бывает. Поелику оптимизируют амортизированное время, гарантируя что среднее время вставки будет оставаться константой. Причем, без какого либо тамогочения шагов А вот как достигнуть того же самого с вашим настраиваемым шагом я пока не увидел.
0
|
2082 / 1573 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
|
|
07.04.2016, 10:59 [ТС] | 27 |
Ага. Только на каждый нод ее все равно выделять. А вот с таким подходом как у вас жители Виларибо будут ждать выделения места на винте гораздо дольше чем жители Вилобаджо выделят буфера только там где они необходимы. Да кстати, ООП программы как раз обычно очень очень большим количеством подобных узлов деревьев оперируют. И увеличивать им количество элементов пропорционально уже существующим в списке тоже вредно, а особенно умножать на 2. Потому как объекты имеют свойство генерироваться по командам пользователя либо по одному либо в известном до вставки количестве на одну генерацию. При десериализации размер тем более известен заранее (во всяком случае при толково разработанном формате файла).
Не будет. Так как очень быстро память начнет не в RAM а на HDD выделяться. Оверхед по размеру скушает все преимущества от пропорционального увеличения размера. Да кстати при добавлении удалении только в начало/конец с кольцевым буфером (гораздо более актуально чем вектора для организации всяких очередей и т.п.) или с массивом со страничной организацией памяти (актуальны на больших последовательностях) они тоже никогда по скорости не сравнятся. Ну а при рандомной вставке удалении ни о каком константном времени говорить не приходится. Оно только у деков константным может быть в таком случае, да и то при указании не номера а адреса элемента перед которым вставлять. Ну а для относительно небольших последовательностей, особенно которые занимаются преимущественно накоплением связей (подавляющее большинство случаев использования динамических массивов) таки получается c GrowStep оптимальней. Хотя опять же. Многое зависит: От того что считать временем. Поелику если есть понятие таймфрейм, то лучше замерять приход элементов в течение таймфрейма и поставить GrowStep большим чем этот приход, чтобы гарантировать не более одного реалока в течение таймфрейма, и при этом минимизировать оверхед по памяти,что особо актуально если данные в конце таймфрейма вытесняются на диск осью (меньше время выгрузки в конце таймфрейма и подгрузки в начале). При этом исключаются просадки в отдельно взятых таймфреймах (просадки плохи тем что снижают точность определения запаса вычислительной мощности). Опять же если пользуются несколько массивов то пусть лучше каждый реалочится в каждом таймфрейме, зато гарантированно виден запас вычислительной мощности, чем совпадет реалок нескольких (достаточно редкое явление) в одном таймфрейме и оного запаса не хватит. Рандомные лаги в игрухах видели? Очень часто причина именно в совпадении реалоков нескольких векторов в одном таймфрейме при недостаточном запасе вычислительной мощности. В игрухе поматерились по поводу разбившегося из за этого самолета и будет. А в реале? Но вообще при таких раскладах более оптимальна страничная организация, с задаваемым размером станицы, а обычный массив с GrowStep пользуется для хранения адресов страниц. Вообще реалтаймовые алгоритмы местами сильно отличаются от нереалтаймовых. Хотя бы тем что необходимо оптимизировать не общее время а гарантированно уложится в каждый тамфрейм, причем очень желательно с небольшой разницей между отдельно взятыми таймфреймами. Добавлено через 53 минуты Как-как. Выделяется новый кусок побольше. В него все копируется. Потом старое удаляется. А страничная организация - массив страниц по 2^k элементов в каждой странице. Нужно увеличить размер - выделили еще страницу, добавили ее в массив страниц. а в operator [] выбираем элемент как Data[Id>>k][Id&((1<<k)-1)]; Рост вообще очень быстрый. Причем как спереди так и сзади. Ужатие тоже. Но как видите есть небольшой оверхед при доступе. Добавлено через 54 минуты Выбросьте свой дебаггер. На что мелкомягкий убитый в этом плане, но и тот останавливается, хотя и где то на 2 вызова глубже. Борландовский прямо на этот trow становится. И в обоих дебагерах можно подняться вверх по стеку вызовов посмотреть какие значения у переменных из которых индекс вычислялся (ну или вообще данные которые привели к сбою). Ну а если пустить дальше, то да, пойдет выходить из всего и вся до ловушки. Добавлено через 5 минут Бывает. Только разработчики STL об этом ни разу не в курсе. Добавлено через 11 минут Хотя дело даже не в том что надо определится по чем оптимизировать. Главный вопрос в том что универсально подходящей везде оптимизации быть просто не может. Для примеру: тому же массиву со страничной организацией для выполнения своих внутренних операций нужен массив с копированием при ресайзе. При этом к примеру локальному массиву (для промежуточных данных) живущему внутри метода, вполне возможно и важно быстрое наращивание количества элементов. А вот долгоживущему массиву-полю, хранящему связи объекта, таки важна оптимизация по памяти и скорости доступа. Добавлено через 13 минут При этом в большинстве случаев добавление будет в рандомную позицию, а не в конец, т.к. всем известно что неупорядоченные связи ведут к std (sexually transmitted disease - заболевания передаваемые половым путем (толковый словарь английского языка).
0
|
1550 / 875 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
|
|
07.04.2016, 12:53 | 28 |
С чего бы вдруг ему останавливаться на обработанном исключении. Вы сами писали:
Дебагер должен останавливаться не каждом штатном вызове?
0
|
2082 / 1573 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
|
|
07.04.2016, 14:10 [ТС] | 29 |
С того что он дебаггер. Работа у него такая - на точках останова и экскепшинах останавливаться.
На экскепшине останавливается. Если так и задуманно можно запустить дальше или даже пометить что дебагеру по этому типу экскепшинов не останавливаться. В том то и дело что экскепшен это пригодная к обработке нештатная ситуация Добавлено через 12 минут И останавливается он не в месте обработки а в месте выброски. т.е. оно на этот момент времени еще свежее и необработанное и даже не передавшее управление из того места где выброшено.
0
|
1550 / 875 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
|
||||||
07.04.2016, 14:14 | 30 | |||||
Вот нахрена это нужно, если есть assert - специальный инструмент для отладки?
Если ваш дебагер остановится здесь:
0
|
2082 / 1573 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
|
|
07.04.2016, 14:25 [ТС] | 31 |
Давно устаревший. Как минимум 20 лет.
С++ Builder остановится в строке 2, MSVC на пару вызовов из строки 2 глубже. Естественно при запуске через Debug Kernel из IDE. При запуске без Debug Kernel никаких остановок естественно не будет. Добавлено через 5 минут Для того чтобы увидеть не только номер строчки в которой мы узнали об ошибке, но и всю трассу которая к этой ошибке привела и в т.ч. объект в котором она возникла.
0
|
1550 / 875 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
|
|
07.04.2016, 14:26 | 32 |
0
|
2082 / 1573 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
|
|
07.04.2016, 14:33 [ТС] | 33 |
А вы что хотите их по записям в черных ящиках отлаживать? Так это слишком дорого да и черные ящики далеко не всегда находят.
Вообще бывают два вида нештатных ситуаций - не связанные с алгоритмом разрабатываемой программы (т.е. отсутствие файла, отсутствие связи по сети и т.п.) и связанные непосредственно с алгоритмом - т.е. вылет за пределы массивов, обращение по висящим указателям и т.п. Пока возникают экскепшины по второму виду ни о какой работоспособности кода говорить нельзя, а значит нельзя и запускать его в продакшн. А вот в отладке именно этих ошибок остановка по экскепшинам очень здорово помогает.
0
|
1550 / 875 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
|
||||||
07.04.2016, 14:41 | 34 | |||||
И? Посмотрите стек вызовов.
А когда они уже не возникают (в продакшене), никаких throw не должно быть. Так assert и работает. Этим:
0
|
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
|
|
07.04.2016, 17:50 | 35 |
У вас там все еще эпоха "640 килобайт хватит всем"? Еще одна планочка памяти на 16 гигабайт в Виларибо, обойдется куда дешевле нового процессора в Вилабаджо.
Еще раз, для тех кто в танке - реалок тормозит пропорционально размеру массива. То есть, при должном размере массива сожрет любые "запасы вычислительной мощности" и добавки попросит. Поэтому, оптимизировать можно только среднее время работы. Ну или пилить вектор заточенный под строго определенные размеры.
0
|
8972 / 4318 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
|
||||||||||||||||
07.04.2016, 18:45 | 36 | |||||||||||||||
пробовал. это не ваш случай.
я мог бы понять позицию человека, который сказал бы: я знаю stl, просто мне он не нравится. но ваша позиция: не знаю, и знать не хочу. это - позиция неосилятора. они не занимаются велосипедированием стандартной библиотеки (которую сами же и изготовили). это не имеет никакого отношения к эксепшен-бреду, который вы постулируете. специально для вас выше написал: тоже самое, что и с эксепшенами. любая моральная иде покажет стек вызовов. нет. вы похоже так и не поняли. вот вам пример:
корректности вызывающей стороны. в дебаге он проконтролирует, что то, чего не должно быть - не будет. во втором случае - эксепшен. пользователь может ввести все что угодно. самолет не должен упасть и разбиться, только потому, что пилот нажал не на ту кнопку. такие данные всегда должны проверяться. проверка не должна выпиливаться из релиза. и у вызывающей стороны должна быть возможность реализовать сценарий на случай отказа. вот именно для того, что бы вызывающая сторона могла реализовать сценарий восстановления после некорректных данных, и был создан механизм исключений. не предназначен для отладки. он предназначен для отказоустойчивости. выше я задал вам вопрос, на который вы мне так и не дали морального ответа. рассмотрим пример:
я спрошу вас ещё раз: вы ловушки тоже под дебажные дефаны закатываете?
0
|
2082 / 1573 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
|
||||||
08.04.2016, 04:00 [ТС] | 37 | |||||
Она появилась гораздо позже чем более продвинутые средства. Зачем мне лезть в дебри малочитабельного говнокода который не имеет средств для решения необходимых мне задач?
Добавлено через 1 минуту Представьте что в самолете вообще нет пилота. Но от этого абсолютно ничего не меняется. Добавлено через 8 минут А вот это не очень хорошая практика. Потому как во первых ввод надо проверять, вне зависимости есть ли внутренние проверки внутри компонентов-вычислителей. Во вторых проверки для рандомного доступа дают ужасный оверхед при последовательном, при этом и рандомный в большинстве случаев имеет групповую внешнюю проверку. Пример:
Соответсвенно, проверки включены на стадии отладки, только для того чтобы отладить корректность вычисления входных данных. Опять же. Если входные данные не вводятся непосредственно а как либо вычисляемы, что и есть в подавляющем большинстве случаев, то екскепшен ну ничего хорошего тоже не сулит. Ассерт тем более. Так или иначе аварийное завершение всей программы при ассерте, или как минимум какой либо ее ветки вычислений при екскепшине. Результат тот же - птичка на земле. Добавлено через 49 минут Если вы не умеете использовать его для отладки то это не значит что он для этого не предназначен. Основа отказоустойчивости в корректности работы программ. trow это еще и инструмент который способен сообщить о некорректности программы на этапе отладки. В корректной программе возникновение таких экскепшинов исключено, в следствие невозможности срабатывания проверок их выбрасывающих. Соответсвенно в релизе все эти проверки выпиливаются. Добавлено через 4 минуты Поясните что делает ваш close, и что вы видите аморального? Добавлено через 5 минут В большинстве случаев ловушка одна в самом верху. В остальном же ловушки как обычно - на открытии файлов, инициализации сетевых коннекций, и т.п, т.е. там где exception используется как возврат результата обращения к стороннему коду. А те екскепшины которые по выходу за границы массива и т.п. вообще предназначены исключительно для ловли их дебаггером. Потому что никакая осмысленная обработка таких ситуаций кроме изменения кода программы невозможна. Добавлено через 9 минут Посмотрите в код хотя бы тех же экземплов в составе DirectX. Упоминания stl:: есть три раза где то на задворках вспомогательного кода. А в основной работе пользуются более другие средства. Например CGrowableArray вместо std::vector Добавлено через 3 минуты При выходе за границы массива причиной отказа является вызывающая сторона, и кроме изменения кода вызывающей стороны с этим ничего не поделаешь. Так же как к примеру и при попытке установки отрицательного GrowStep. В отличии к примеру от эскепшинов при недостаточном количестве памяти при реалоке. Эти никуда не выпиливаются. Добавлено через 4 минуты Нет у нас эпоха гигантских моделей. Добавлено через 3 минуты Приводился пример - массив со страничной организацией. Оптимизирует и использование памяти и скорость ставки в конец. Но при этом ценой оверхеда при доступе. Опять же. Зависит от назначения. Если массив живет дольше одного таймфрейма то оптимизировать нужно время затрачиваемое в одном таймфрейме и равномерность распределения затраченного времени между таймфреймами. Добавлено через 2 минуты После чего жителям Виларибо прийдетсяя скинутся на более дорогой процессор с большим количеством кеша чем жителям Вилобаджо Добавлено через 10 минут Во первых в отличии от assert это очень помагает при отладке. Во вторых подсмотрено у Борланда. Это в строке убрали выпиливание да и то под вопросом. А в списках TList как было так и осталось. Добавлено через 1 минуту А еще лучше набор векторов под разные сценарии использования. Добавлено через 10 минут Покажет. Только этот стек нужно видеть в момент возникновения ошибки. При этом иметь возможность не только видеть стек но и перейти в место вызова и посмотреть локальные данные вызывающих в момент возникновения ошибки. Именно экскепшн и позволяет останавливаться в момент возникновения ошибки без раскидывания брекпоинтов по всему коду. Это при наличии кода вызываемой стороны. А при отсутствии брекпоинты и кидать не куда (извращения в духе дизассемблировать и найти куда бряк тыкнуть не рассматриваем). Но все равно остается возможность остановится именно на сбойном вызове. Если заметили даже штатные либы от всех производителей идут в двух видах бинарника - debug и release. Чем они по вашему отличаются кроме выпеленной в release части проверок? Добавлено через 5 минут Ну ну. Каждый лишний байт в структуре данных запросто может вылиться в лишние 100MB в структуре модели. и это далеко не предел.
1
|
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
|
|
08.04.2016, 04:18 | 38 |
Кстати, вы в курсе про модификатор nothrow?
Если у вас там что-то гигантское, переполняющее 16-гигабайтовые планки памяти, то используется B-дерево и ему подобные структуры. И там все равно двукратный оверхед по памяти. Если вы про "дораспределять страницы размером кратным степени двойки", то оно достигается ценой не константного времени доступа по индексу. Ибо номер страницы будет равен номеру старшего бита индекса, а нахождение старшего бита - логарифмическая сложность. "Массивом" такое является в той же степени, что и std::map<int,int>. Не придется. Если элементы массива в конце узла никто не читает, на загрузку кеша они никак не влияют, даже если их там миллион. Исключая, конечно, вырожденный случай "узлы идут в памяти строго друг за другом и читаются строго по порядку".
0
|
2082 / 1573 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
|
|
08.04.2016, 04:46 [ТС] | 39 |
При размере страницы 2^k номер страницы будет Id>>k. А номер элемента в странице (Id&(1<<k-1)). Для произвольного же размера страницы номер страницы будет Id/PageSize а номер элемента Id%PageSize. При этом подразумевается что для отдельно взятого массива размер страницы постоянен весь его жизненный цикл.
Как будто никогда банки видеопамяти не переключали ей богу. Может все роблемы что эпоху "На всех 640k" не застали? У меня просто деревья объектов. К примеру как на форме ввода вывода. В принципе по организации ничем от этого не отличается к примеру компановка модели ЛА из объектов-подузлов, так же как и компоновка модели города из отдельных зданий состоящих из составных частей, так же и иерархия 3D сцены и т.д. и т.п. И все эти штуки должны хранить и изменять свои состояния и взаимосвязи и в соответствии с ними так или иначе взаимодействовать. И если зданий от 100K, итемов вообще немерянно, управляемых пользователем объектов тоже десятки тысяч... при этом состояние каждого объекта тоже может быть набором объектов содержащих взаимосвязи. Если они статически прописаны в последнем узле (этот ваш массивчик для ускорения 16 элементов) то и в кеш они пойдут вместе с самим узлом. Ну почему же вырожденный? Если подгрузка дерева была одним махом из файла то лежать узлы будут по порядку. Ну а страничек у кеша много, поэтому в кеше будут страницы содержащие наиболее часто используемые страницы памяти содержащие узлы. Меньше размер узла - больше узлов в кеше. Больше размер узла - для такого же количества узлов в кеше нужен больший кеш. При этом учитывая что огромная часть обработки крутится обычно по соседним в памяти узлам (нод и его прямые потомки, во всяком случае при создании дерева путем десериализации файла они обычно где то рядом) то и в кеш они будут попадать примерно теми группами которые обрабатываются.
0
|
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
|
|
08.04.2016, 05:34 | 40 |
А я подумал что k растет вместе с массивом и он получается списком из страниц на 2, 4, 8, 16... 2^k элементов.
Если брать фиксированное 2^k, то все еще хуже. Размер страницы маленький - тормозит реалок списка страниц. Размер страницы большой - просто дикий оверхед по памяти, мой буфер на 16 элементов и рядом не лежал. Зданий от ста тысяч, в каждое здание злой Renji добавил буфер на 16 интов. А это, между-прочим, 64 байта. 100 000 зданий*64 байта, итого шесть с хвостиком мегабайт. Если для вас шесть мегабайт - серьезная трата, отнесите свой ПК в музей наконец. Потому что в кеше содержатся не четырехкилобайтовые страницы, а 32/64 байтовые кеш-ряды. И вероятность того что два наугад взятых узла дерева совершенно случайно оказались в одном кеш-ряде крайне мала. А если не оказались - полный ряд придется читать и тому узлу, и другому. А то и все два ряда, так как вы же выравниванием данных на границу 32/64 байт не озаботились, да?
0
|
08.04.2016, 05:34 | |
08.04.2016, 05:34 | |
Помогаю со студенческими работами здесь
40
error LNK2019: ссылка на неразрешенный внешний символ "public: __thiscall Vector<int>::Vector<int>(void)" (?0?$Vector@H@@QAE@XZ) в функции _main О возможностях С++ Как можно увеличить размер вектора, который является элементом вектора vector<vector<int>>arr(n, vector <int>) О возможностях ACCESS О возможностях Java Вопрос о возможностях Delphi Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |