![]() |
|
Модераторы: Се ля ви |
![]()
|
|
| Sardar |
|
|||
![]() Бегун ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 6986 Регистрация: 19.4.2002 Где: Нидерланды, Groni ngen Репутация: 1 Всего: 317 |
Все знают что аллокации переменных на стеке быстрей чем в куче (heap memory), НО! откуда это пошло и так ли это сейчас?
Раньше push/pop'или простые значения, сейчас порой сложные обьекты. При создании обьекта на стеке просто поднимают выше значение регистра-указателя-на-верхушку-стека (SP), далее идёт инициализация "полей". При этом вся работа со стеком это увеличение/уменьшения SP, сама инициализация происходит обычными инструкциями по работе с памятью (не мнемоники имею в виду, физически те же инструкции) относительно SP. Плюсы подхода:
Вторая проблема памяти это её выделение операционной системой. Физически нельзя выделить один int (да, иногда пишут new int Теперь начнём работать с памятью как со стеком. Стек это общий ресурс, каждый тред может иметь сколько угодно стеков на котором можно создавать/удалять обьекты. Выделяеться память под обьект просто повышая указатель, освобождаеться просто пометкой (не освобождаеться физически). Время от времени тред приостанвливаеться (остальные могут продолжать работать если не ссылаються на стек этого треда), сборщик мусора уплотняет стек. В таком случае высчитывание адреса по смещению от SP' не возможно, только по указателям, что не страшно. Кеширование как и у стека, если создаём и тут же удаляем массу мелких обьектов (обычный ООП подход), то все они в кеше, соответственно работа быстра. Организация памяти в стек и сборка мусора есть хорошо проверенная техника, используеться в Java. Вопрос и смысл всего этого флуда: Получаеться что использование "железного" SP и просто регистра для организации собственного стека в памяти разницы не имеет, т.к. и в том и вдругом случае прога сама изменет регистр-указатель, push'ить целый обьект процы не умеют? Как организован стек на отличных от x86 процах? (по моему иногда даже железного SP нет, бери любой из массы регистров). Имея массу стеков можно проще организовывать треды. Вобще по моему можно все локальные данные гонять в одном стеке, а железный пользовать для вызова процедур и передачи аргументов. Тогда после вызова фрейм фрейм собственного стека можно либо освободить целиком, либо приатачить к куче если есть экспортируемые обьекты. Чего вообще в голову приходит глядя на текст выше? И главное: что читать по теме? ссылки, имена, ключевые слова критикующие подход выше очень приветствуються. Восхваление можно найти в дизайнах сборщиков мусора. -------------------- Опыт - сын ошибок трудных © А. С. Пушкин Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik Оценить мои качества можно тут. |
|||
|
||||
| regis |
|
||||||||||||||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 232 Регистрация: 12.12.2005 Где: Москва, Россия Репутация: нет Всего: 7 |
Полагаю, что так.
Вроде-бы, во всех современных ОС стек будет расти со страничной гранулярностью. Так же, впрочем, как и сегмент данных, содержащий хип. Так что, принципиальной разницы не вижу. Если, конечно, речь об этом.
Не совсем понял, почему эта идея опровергнута. Если некоторое количество инструкций, которые надо выполнить в цикле, вынести в одину или несколько подпрограмм, загрузка на внутренние кеши только возрастет (не говоря уж о том, что накладные расходы на вызов/возврат из подпрограмм добавятся).
Строго говоря, память в C/C++ сначала выделяют стандартные библиотеки, и только потом (если подходящего свобободного куска не нашлось) -- ОС. И откуда эта цифра -- 64 байт? Думаю, для стандартных malloc/free дискретность куда меньше -- 16 байт, или что-то в этом роде.
Хммм... Насколько я понимаю в многопоточности, у каждого треда есть собственный стек. Тем не менее, он не перестает быть стеком, т.е. дисциплина LIFO, расширяется-уплотняется как обычно и т.п. И естественно, доступ к данным через SP, а как иначе?
В разных процессорах -- по разному. В достопамятном DEC PDP-11 регистра стэка как такового не было -- использовался регистр общего назначения R6. И ничего, программистам это не мешало. ;)
Опять не совсем понял мысль. (Как в принципе можно организовать многопоточность, НЕ имея "массы стеков"?)
Упорно лезет в голову мысль, что я не уловил суть идеи. --------------------
В. В чем разница между hardware и software?О. В отличие от второго, по первому можно двинуть кулаком или пнуть ногой. |
||||||||||||||||
|
|||||||||||||||||
| Sardar |
|
||||||||||
![]() Бегун ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 6986 Регистрация: 19.4.2002 Где: Нидерланды, Groni ngen Репутация: 1 Всего: 317 |
Как "железный", так и "собственоручно сделанный". Если они упакованы рядом, то нагрузка на кеш как раз снижаеться. Современный кеш > 512кб поделённый на блоки (64 байта по моему чаще всего). Туда запросто влезет цикл и пара мелких функций, если исполнение ограничиваеться только этими инструкциями (например итеративно вычисляем чего нибудь до нужной точности), то фишка работает очень быстро. Если же прога одним полотном, то код приходиться догружать постоянно. Идея пошла отсюда, смысл в том что байткод который обычно меньше по размеру чем транслированный код может быть быстрее, если интерпретатор помещаеться в кеш.
Чем меньше блок, тем больше нод в дереве (чём угодно где блоки регистрируем). Заголовок блока зависит от реализации, я писал менеджер памяти для одного девайса (4Мб RAM всего), на заголовок уходило 8 байт: 2 указателя (24битная адресная шина) + длина блока в 4 байтных еденицах. На современном компе в минимум 2ГБ доступной оперативы как то не серьёзно выделять (заголовк + блок) менее 64 байт... ИМХО
Строго говоря ось не умеет выделять блоки памяти по моему, можно только отодвинуть границу конца виртуальной памяти (добавить "меппингов"). Прога либами распределяет память сама, но это уже детали, вопрос в другом
Имел в виду не железный стек (обновление SP при переключении контекста), а привязка нескольких стеков к треду. Железный стек нужен процу для вызовов функций. Фиксированный лист аргументов удобно тоже положить на "железный стек". Опциональные аргументы и локальные перменные + вообще вычисления можно вести на отдельных стеках, при этом компилер по коду выявляет когда обьект возвращаеться в мир, а когда создаётсья и уничтожаеться в функции. В первомслучае добавляем обьект в отдельный стек, которым приатачим блоком к "куче"(heap). Второе просто растёт и не засоряет железный стек, хотя и потребуеться подгрузить инфу в кешь. Идея в том что нет надобности записывать такую инфу в память, по этому при возврате из функции если проц видит свой кешь, то его можно просто обнулить. Нет обращения к памяти, нет издежки. Ловля блох, но всё же
Как сказал выше "масса стеков" у одного треда. Сам стек может помещаться в некий общий большой сегмент памяти для треда, сегменты с фиксированным размером. Это упрощает сборщик мусора. Другими словами:
Вопрос родился когда я в очередной раз прочёл (в дизайне и критике C--) что создавать обьекты на стеке это быстро. Все кто сравнивает C++ с Java тоже приводят этот аргумент. Отсюда родилась идея с сегментами и стеками. Т.к. идея тривиальна, естественно она уже давно известна и отработанна, НО! к удивленю моему пишут только положительные стороны (вкупе со сборщиком мусора). Меня интересует критика такой организации памяти. Также интересны альтернативы ещё быстрей. Ну и наконец собственные мысли где могут возникнуть проблемы или наоборот успешная железная поддержка, например эффективная синхорнизация сегментов между тредами (атомарные swap/test-set знаем, альтернативы?). Интересны ключевые слова по которым можно найти инфу, без воды, без рекламы, знающими людьми. -------------------- Опыт - сын ошибок трудных © А. С. Пушкин Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik Оценить мои качества можно тут. |
||||||||||
|
|||||||||||
| Cr@$h |
|
|||
![]() Исследователь ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1693 Регистрация: 3.4.2005 Где: Санкт-Петербург, Россия Репутация: 1 Всего: 41 |
Дело в том, что прой умеет выполнять свой собственный код и ничего более. Если байт код сам по себе меньше, это совсем не значит, что при его выполнении процу понадобится выполнять меньшее число операций. В дизайнах сборщиков мусора могут восхвалять что угодно и будут правы. Сейчас это дело довольно хорошо отработано. Хотя истинных алгоритмов тебе никто не скажет. Как говорят разработчики Java -- это "style of art". Уверен применяемые концепции, идеи и методы исключительно хороши для сборщиков мусора, но это вовсем не значит, что выполнение самого управляемого кода будут вестись быстрее, чем неуправляемого. P.S. Надеюсь тредами ты называешь потоки. |
|||
|
||||
| Sardar |
|
||||
![]() Бегун ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 6986 Регистрация: 19.4.2002 Где: Нидерланды, Groni ngen Репутация: 1 Всего: 317 |
Нет, я имел в виду что больше байткода влезает в один "забор в кеш", т.е. меньше обращений к памяти. Сам байткод высокоуровневый, вообще его лучше в threaded код обращать (не путать с потоками, как в Fort'e в смысле). Тогда он компактный и шустрый . Да потоки, только ИМХО не корректное это слово, ассоциируеться с каналами (channel, IO и т.д.)
Почему же, инфы на эту тему масса. Просто часто бывают не обоснованные заявления, одно из них привёл здесь "стек всегда быстрей чем работа с кучей". Соответственно современные менеджеры памяти, та же ява, работают памятью как со стеком (выделение под обьекты). Где то есть сомнения что не универсален этот подход и будут сложности под разными платформами (процами). Потому спросил критику. Значит пока такая организация памяти наиболее быстра, в любом случае быстрей чем традиционный malloc. А что будет если процов станет > 20, малые процы типа Cell? (в PS3 пользуються, их время ещё придёт). Скорость процов будет ниже, за то их будет больше, следовательно выигрывать на кеше станет сложней. Также если сегменты будут расшариваьтся тредами (метод обьекта вызываемый из двух тредов например), то кешь вообще постоянно обнуляться будет. В этом направлении кто нибудь задумывался? -------------------- Опыт - сын ошибок трудных © А. С. Пушкин Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik Оценить мои качества можно тут. |
||||
|
|||||
| Cr@$h |
|
||||
![]() Исследователь ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1693 Регистрация: 3.4.2005 Где: Санкт-Петербург, Россия Репутация: 1 Всего: 41 |
Может быть. У меня с каналом больше pipe ассоциируется
В конечном итоге такие вещи проверяются на практике. |
||||
|
|||||
![]()
|
| Правила раздела "Философия программирования": | |
|
|
Форум "Философия программирования" предназначен для обсуждения вопросов, так или иначе связанных с философскими аспектами разработки ПО: • вопросы перспективного развития методов написания ПО; • изменяющиеся языки и методологии программирования; Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Се ля ви. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Философия программирования | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |