Здравствуйте, prVovik, Вы писали:
V>Далее, в моем случае библиотека использовала фиксированные небольшой буфер памяти,
Ага. На 8 000 сообщений.
Пойми, что все твои рссуждения о скорости выделения памяти — это чистой воды фобии. Если бы писал свою программу на дотенте, то ты бы и не заметил никаких проблем.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
VD>Прошу обратить внимание на то, что это ответ на реплику:
VD>А сообщения одного размера? Ой не верю.
>А вдруг? А может это и вовсе одно и то же сообщение выводимое 10000000 раз в секунду, чтобы поиздеваться над сборщиком мусора?
VD>Оппоненты откровенно неразбираются в сути вопроса и всю свою логику строют на основе совбственных фобий и предубеждений.
Понравилось? Я рад. А может это процитированное пару раз сообщение было написано, чтобы поиздеваться не над сборщиком мусора?
Здравствуйте, prVovik, Вы писали:
V>Конечно, быстрее будет фиксированный буфер небольшого размера с последовательным доступом.
Не факт. V>Могут быть сомнения?
Если буфер выпал из кеша процессора то могут..., а ты там еще про своп говорил...
V>Сервер перестанет принимать новые сообщения, пока не разгребет старые. Пользователей "лаганет".
И как часто он лагает?
V>*мечтательно* эх, а была бы память бесконечной, ее бы тогда вообще не надо было бы освобождать
Память будет освобождена при сборке первого поколения, а оно собирается гораздо реже чем нулевое и к томц времене с большой вероятностью весь блок станет мусором те будет просто помечен как свободный, а если там и останутся живые объекты то скопировать несколько килобайт для современного железа это вобще не проблема.
Вобще 3 поколения нужны для того чтобы эффективно работать в условиях когда существует большое колличество объектов с коротким временем жизни. Большинство объектов умрет в нулевом поколении. В первое поколение попадают долгоживущие объекты и случайно выжившие короткоживущие объекты(они использовались в момент когда произошла сборка нулевого поколения). К моменту сборки первого поколения вероятность того что кто-то ссылается на короткоживущие объекты практичеки равна нулю. Те во второе поколение попадут только долго живущие объекты.
Таким образом сборка нулевого покаления отрабатывает просто мнгновенно(особенно если учесть то что все в кеше процессора), первое поколение используется как буфер для случайно уцелевших объектов, а во втором поколении сидят объекты с длинным временем жизни... их туда сослали чтобы по ногами не путались.
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, VladD2, Вы писали:
VD>Реально и сборка второго поколения не страшна, так как может производиться с помощью Concurrent GC.
Кстати ИМХО лучший вариант для мягкого реалтайма типа игр это собирать нулевое и первое поколение обычным мусорщиком, а второе конкурентным.
VD>И что самое забавное порождающие при этом монстров вроде ФИРА.
Я его на своей машине так и не смог запустить... хотя машина зверь... четвертая квака летает. Может конечно компакт кривой попался...
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, prVovik, Вы писали: V>>При чем тут ассемблер и высокоуровневые языки? VD>При том, что ручное уравление памятью ничем не отличается от ручного управления кодогенерацией.
Хм... Ничего не понял. А что общего между кодогенерацией и алгоритмами управления памятью?
VD>Пойми. И GC и неуправляемые коучи пишут не идеоты.
Не сомневаюсь в этом. Но они и понятия не имеют о МОЕЙ задаче.
VD>И если у меня скоростная характеристика близка к O(1), то хоть в лепешку разбейся но серьезного выигрыша ты неполучишь.
Неужели? А если константа будет час?
VD>Знаешь, как легче всего получить выигрыш от собственной реализации кучи?
Во-первых, я ничего не говорил про реализацию собственной кучи. Куча — это вещь универсальная. Я же речь вел об управлением памятью в контексте некоторой задачи.
VD>Просто не задействовать в ней защиту от многопоточного доступу. Блокировки (даже самые легкие) отнимают основное время при выделении памяти.
Ну вот ты и сам сказал, что универсальное средство не всегда оптимально. Именно об этом я и толковал. Точнее о том, что хорошо, когда средство разработки предоставляет возможность удобно реализовать вещи, которые не были предусмотрены создателями данного средства разработки. ТО есть тут имеет место старый спор о том, что лучше: много-много рыбы, или удочка. Я хочу сказать, что на данный вопрос невозможно дать однозначный ответ и очень часто случается, что предпочтительнее иметь удочку, а не рыбу.
VD>В ЖЦ, выделение памяти в них деалется просым инкрементом. И основные затраты тут тоже на блокировку.
Прямо как в том анекдоте про студента, который попал в студенческий ад. Пол года веселился, а потом пришел черт и начал вбивать в зад гвозди.
V>>Это был проект сетевого движка для MMORPG. Приходило 8к сообщений (разного размера) в секунду и управление памятью как раз было узким местом. VD>Так, все! На этом мы пожалуй закончим. В сумашедший дом я не играю.
Ты о чем?
VD>Читай классику: Оптимизация – ваш злейший враг
Давай без снизходительного тона, ок? Ты думаешь, что я от нечего делать занялся оптимизацией? Естественно, сначала все было сделано "в лоб", и когда глянули на производительность, пришлось прослезиться. А потом профайлер в зубы и вперед.
VD>Бнин, свой хип для оптимизации 8 000 выделений объектов в секунду, да еще в программе которая по определению не предвявлет особых требований к производительности.
Во-первых, требования к производительности были очень жесткими. Во-вторых, читай выше, не хочу повторяться.
Здравствуйте, igna, Вы писали:
I>Это да. Но то, что на C# можно писать не создавая мусора, не отменяет того, что библиотека .NET Framework иногда создает его там, где это не является необходимым; например StreamReader.ReadLine при каждом вызове возвращает новый String, и в классе StreamReader нет метода читающего в имеющийся StreamBuilder.
По сравнения с чтением с диска...
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, prVovik, Вы писали:
V>>Далее, в моем случае библиотека использовала фиксированные небольшой буфер памяти,
VD>Ага. На 8 000 сообщений.
Что смешного?
Здравствуйте, prVovik, Вы писали:
VD>>Пойми. И GC и неуправляемые коучи пишут не идеоты. V>Не сомневаюсь в этом. Но они и понятия не имеют о МОЕЙ задаче.
Вот только главный прикол в том что ГЦ как будто специально оптимизировали под твою задачу.
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
I>>... StreamReader.ReadLine при каждом вызове возвращает новый String, и в классе StreamReader нет метода читающего в имеющийся StreamBuilder.
WH> По сравнения с чтением с диска...
Здравствуйте, igna, Вы писали:
I>Кто сказал? Почему с диска?
Ну еще может быть из сети... да еще и через дешифратор с декомпрессором...
Короче ИМХО случаи где можно заметить создание этой строки настолько редки что создатели фреймворка решили с этим не заморачиваться. К тому же если у нас ReadLine то поток текстовый... а текстовые данные в критических к производительности местах обычно не гоняют. Ну не сочетается текст с выжиманием производительности. Ну никак.
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, eao197, Вы писали:
E>Как я понимаю, речь шла не о 8K объектов в секунду, а об обработке 8K сообщений в секунду. Еще не известно, сколько и чего создавалось во время обработки одного сообщения. А обработка 8K сообщений в секунду в сетевом приложении это не кисло.
2VladD2: а минус за что? С чем конкретно ты не согласен?
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, prVovik, Вы писали:
V>>Конечно, быстрее будет фиксированный буфер небольшого размера с последовательным доступом. WH>Не факт. V>>Могут быть сомнения? WH>Если буфер выпал из кеша процессора то могут..., а ты там еще про своп говорил...
А ничего, что ГЦ старается "сожрать" как можно больше памяти, она что, типа вся целиком в кеше помещается и никогда не выпадает?
А про своп я говорил, чтобы подчеркнуть, что из всего буфера активно используется только маленькая его часть, которая, кстати, и будет находиться в кеше.
V>>Сервер перестанет принимать новые сообщения, пока не разгребет старые. Пользователей "лаганет". WH>И как часто он лагает?
А хз
Это уже были не мои проблемы.
V>>*мечтательно* эх, а была бы память бесконечной, ее бы тогда вообще не надо было бы освобождать WH>Память будет освобождена при сборке первого поколения, а оно собирается гораздо реже чем нулевое и к томц времене с большой вероятностью весь блок станет мусором те будет просто помечен как свободный, а если там и останутся живые объекты то скопировать несколько килобайт для современного железа это вобще не проблема.
WH>Вобще 3 поколения нужны для того чтобы эффективно работать в условиях когда существует большое колличество объектов с коротким временем жизни. Большинство объектов умрет в нулевом поколении. В первое поколение попадают долгоживущие объекты и случайно выжившие короткоживущие объекты(они использовались в момент когда произошла сборка нулевого поколения). К моменту сборки первого поколения вероятность того что кто-то ссылается на короткоживущие объекты практичеки равна нулю. Те во второе поколение попадут только долго живущие объекты. WH>Таким образом сборка нулевого покаления отрабатывает просто мнгновенно(особенно если учесть то что все в кеше процессора), первое поколение используется как буфер для случайно уцелевших объектов, а во втором поколении сидят объекты с длинным временем жизни... их туда сослали чтобы по ногами не путались.
Обрати внимание. При реализации этой стратегии принималась во внимение некоторая частность о характере управления памятью, а именно, утверждение, что чем раньше был создан объект, тем больше вероятность, что он скоро будет уничтожен. И нетовский ГЦ был создан с ориентировкой именно на эту частность. Да, согласен, что это наиболее распространенная схема управления памятью (кстати к другим ресурсам это уже относится в меньшей степени), и высокая производительность этого ГЦ как раз и обусловлена на заточку под эту схему управления памятью.
Все хорошо, когда программа укладывается в стандартные рамки нетовского ГЦ LIFO (последним создался — первым удалишься — LCFD скорее ), все замечательно работает. Примеры супер-быстрой работы такого ГЦ на схеме использования памятью, на которую он расчитан, неоднократно приводились. Это, лишь, доказывает, что код, занимающийся управлением памятью должен знать о характере ее использования. Но случаи бывают разные. Вот помню, как Сергей Губанов как-то приводил пример, в котором "убогий" обероновский ГЦ "рвал" дотнетовский. А все потому, что схемы использования памяти была не LIFO (LCFD), а FIFO (FCFD). А вот если бы дотнетовский гц был ориентированн на последнюю схему, все было бы иначе . Это я к тому, что не бывает серебрянных пуль, которые хорошо работают во всех случаях. Для каждого супостата нужен свой снаряд
Здравствуйте, prVovik, Вы писали:
V>А ничего, что ГЦ старается "сожрать" как можно больше памяти, она что, типа вся целиком в кеше помещается и никогда не выпадает?
Размеры нулевого и первого поколений фиксированы. Растет второе поколение в котором сидят долгоживущие объекты.
Сообщения из твоей задачи туда не попадут. V>А про своп я говорил, чтобы подчеркнуть, что из всего буфера активно используется только маленькая его часть, которая, кстати, и будет находиться в кеше.
Те делаем вывод что сервер очень оперативно выгребал сообщения. А заторы были очень редки. Так?
V>Обрати внимание. При реализации этой стратегии принималась во внимение некоторая частность о характере управления памятью, а именно, утверждение, что чем раньше был создан объект, тем больше вероятность, что он скоро будет уничтожен. И нетовский ГЦ был создан с ориентировкой именно на эту частность. Да, согласен, что это наиболее распространенная схема управления памятью (кстати к другим ресурсам это уже относится в меньшей степени), и высокая производительность этого ГЦ как раз и обусловлена на заточку под эту схему управления памятью.
Причем твоя задаче прекрасно в эту схему укладывается. А другими ресурсами в .NET релят ручками. Причем лично мне using + IDisposible хватало всегда.
V>Все хорошо, когда программа укладывается в стандартные рамки нетовского ГЦ LIFO (последним создался — первым удалишься — LCFD скорее ), все замечательно работает. Примеры супер-быстрой работы такого ГЦ на схеме использования памятью, на которую он расчитан, неоднократно приводились. Это, лишь, доказывает, что код, занимающийся управлением памятью должен знать о характере ее использования. Но случаи бывают разные. Вот помню, как Сергей Губанов как-то приводил пример, в котором "убогий" обероновский ГЦ "рвал" дотнетовский. А все потому, что схемы использования памяти была не LIFO (LCFD), а FIFO (FCFD).
Ссылку пожалуйста. Чтото мне мерещится что когда к этому тесту добавили 1000000 вечно живущих объектов (те создали болие или мение реальные условия) оберон просто умер.
Короче не работающая программа можер работать сколь угодно быстро... V>А вот если бы дотнетовский гц был ориентированн на последнюю схему, все было бы иначе . Это я к тому, что не бывает серебрянных пуль, которые хорошо работают во всех случаях. Для каждого супостата нужен свой снаряд
Бывают посоребренные пули которые хорошо работают в подавляющем большенстве случаев. И для твоего супостата эти пули прекрасно подходят.
Единственный случай когда я отказался от услуг ГЦ в .NET это был бинарный дифф для того чтобы резать на куски бэкап быза RSDN'а. Но там сценарий работы был таким: В начале работы создать несколько миллионов одинаковых объектов, а в конце работы их все удалить. Для этого я воспользовался массивом value типов.
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
WH>Те делаем вывод что сервер очень оперативно выгребал сообщения. А заторы были очень редки. Так?
Так, но не забывай, что само по себе время жизни объекта мало что значит. Важно время жизни относительно других объектов. Я не знаю, что именно делал сервер во время обработки каждого сообщения (а делать он мог много чего ), но факт есть факт: сообщения жили по принципу первое создалось, первое удалилось.
Здравствуйте, igna, Вы писали:
I>Может быть, но было так: Пытаюсь сохранить новую запись, нет места. Удаляю некоторые ненужные записи и пытаюсь сохранить еще раз. Телефон "зависает" секунд на 10, потом сохраняет запись. Наблюдал такое поведение несколько раз. Siemens M55.
Siemens M55 вроде как на Symbian OS живет. И телефонная книга у него не на Яве значит.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, prVovik, Вы писали:
V>По поводу большенства мертвых объектов. Доставала объекты оснавная программа (сервер), а не сетевая библиотека. И когда сервер соизволит достать очередное сообщение — это только серверу известно, и сколько поколений переживут сообщения в буффере тоже не понятно. Далее, подумай про объемы: 8к сообщений в секунду, каждое из которых в среднем по 4 килобайта. Получаем 32 мегабайта в секунду. Некислая я скажу нагрузка на ГЦ будет — дефрагментация получится очень "вкусной" операцией
Ну ты заливаешь! Ты прежде чем токое нести узнал бы какова средняя пропускная способность у 100 мегабитной сети. Я тебе как краевед скажу, что где-то оголо 10 мег в секунду.
На вашей игрушке можно смело писать звучные лозунги вроде:
Мы работаем на будущее!!!... Минимальные требования для сетевой игры Gigabit Ethernet!
А вот для ЖЦ это тем не менее вообще не работа. Вот простенький тест:
using System;
using System.Collections.Generic;
using System.Diagnostics;
class Program
{
static void Main()
{
Stopwatch timer = Stopwatch.StartNew();
List<char[]> list = new List<char[]>(100);
for (int i = 0; i < 8000; i++)
{
list.Add(new char[4 * 1024]);
if (i % 100 == 0)
list.Clear();
}
Console.WriteLine(timer.Elapsed);
for (int i = 0; i <= GC.MaxGeneration; i++)
Console.WriteLine("Количество сборок в поколнии {0}: {1}", i, GC.CollectionCount(i));
}
}
Вто что получается на маей машине:
00:00:00.0547748
Количество сборок в поколнии 0: 17
Количество сборок в поколнии 1: 6
Количество сборок в поколнии 2: 0
На этом хочу закончить эту позновательную беседу. Дела, знаете ли, ждут. Фэнтези определенно не мой любимый жанр.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, prVovik, Вы писали:
V>Так, но не забывай, что само по себе время жизни объекта мало что значит. Важно время жизни относительно других объектов. Я не знаю, что именно делал сервер во время обработки каждого сообщения (а делать он мог много чего ), но факт есть факт: сообщения жили по принципу первое создалось, первое удалилось.
Ну не верю я в что эти объекты попадут дальше первого поколения. И как следствие не будет просадки по производительности.
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, prVovik, Вы писали:
VD>>Ага. На 8 000 сообщений. V>Что смешного?
"фиксированные небольшой буфер памяти" в количестве 8000, да еще и с размером по 4 К — это 32 метра! И это при том, что сообщения-то идут последовательно.
Здравствуйте, WolfHound, Вы писали:
WH>Кстати ИМХО лучший вариант для мягкого реалтайма типа игр это собирать нулевое и первое поколение обычным мусорщиком, а второе конкурентным.
Так и делается. Вообще-то я об этом в статье написал (из #5 2005). Тебе как члену команды она доступна. Так что можешь почитать. Там об этом как раз и рассказывается.
VD>>И что самое забавное порождающие при этом монстров вроде ФИРА. WH>Я его на своей машине так и не смог запустить... хотя машина зверь...
Я на домашней запустил. Там 6800 GT с 128 метрами.
Правда пришлось час провести в их тесте (слава богу хоть его сделали) и выяснить что нужно отключить. Основное что пришлось отключиь — это мягкие тени.
WH>четвертая квака летает. Может конечно компакт кривой попался...
4 Квака у меня летает и на машине с ATI 9800 Pro. Причем мягкие тени там не хуже ФИРА.