Здравствуйте, Ikemefula, Вы писали:
I>А за счет чего gc исключается ? Вот надо хранить миллиард строк. Как это будет храниться в пуле ?
1. Храним структуры.
2. Структуры храним в массиве из пула. Нужен динамический размер — собираем список из сегментов из пула.
Ну да, оно очень ограничено по сценариям использования, да и произвольные структуры данных поверх так просто не построишь, но у NFX Pile ровно те же проблемы.
Здравствуйте, Sinix, Вы писали:
S>1. Храним структуры. S>2. Структуры храним в массиве из пула. Нужен динамический размер — собираем список из сегментов из пула.
Что хранить — понятно. Как сохранить в твой буфер миллиард строк ?
S>Ну да, оно очень ограничено по сценариям использования, да и произвольные структуры данных поверх так просто не построишь, но у NFX Pile ровно те же проблемы.
NFX Pile для GC торчит как ровно один большой объект. Миллиард строк будет все равно одним объектом.
NFX из за серилизации может хранить вообще всё что угодно.
Здравствуйте, Ikemefula, Вы писали:
I>Что хранить — понятно. Как сохранить в твой буфер миллиард строк ?
кэп: ну а зачем тебе непрерывный буфер, если под капотом можно работать с сегментами?
Для по максимуму разгрузить GC — вэлкам в MappedMemoryFiles с его ReadArray<T>, или извращаемся с unmanaged heap по вкусу.
Также см. главу два (Garbage Collection) в Writing High-Performance .NET Code, она практически вся про сабж.
Здравствуйте, Sinix, Вы писали:
I>>Что хранить — понятно. Как сохранить в твой буфер миллиард строк ? S>кэп: ну а зачем тебе непрерывный буфер, если под капотом можно работать с сегментами?
Похоже, кого то вопрос задел за живое. Так и говори — никак.
S>Для по максимуму разгрузить GC — вэлкам в MappedMemoryFiles с его ReadArray<T>, или извращаемся с unmanaged heap по вкусу. S>Также см. главу два (Garbage Collection) в Writing High-Performance .NET Code, она практически вся про сабж.
Спасибо, но я не спрашивал у тебя советов, как разгрузить GC. Давать советы, когда тебя не просили — хамство.
Здравствуйте, Ikemefula, Вы писали:
I>Похоже, кого то вопрос задел за живое. Так и говори — никак.
Не угадал. Смысл повторять то, что уже отвечал, да ещё и без сарказма? Скучно же.
Я всё расписал в стартовом ответе, если потерял нить обсуждения:
А. Только managed code
* используем buffer pool, выделяем из него сегменты, наворачиваем поверх коллекцию или stream, заполняем структурами. Vladek выше давал ссылку на RecyclableMemoryStream, там в документашке всё есть как бы.
* других вариантов без unmanaged нет. Надо объяснять почему?
Б. Количество сегментов настолько большое, что они сами по себе создают gc pressure. Правда, для этого надо выделить гигов эдак 10-20 (считаем сегменты в 65к), активно насиловать gen2 и использовать client gc, т.е. быть полным злым буратиной.
Ну ок, лечится элементарно: перекидываем буферы в MMF/свой unmanaged pool.
В. Объекты не влезают в память. Тут как бы очевидно — любая in-process db/distributed cache (смотря по обстоятельствам)
Собственно вопрос на миллион долларов: куда тут приткнуть pile? И нафига дёргаться _до_ момента, когда мы действительно уткнёмся в GC?
I>Спасибо, но я не спрашивал у тебя советов, как разгрузить GC. Давать советы, когда тебя не просили — хамство.
Ну да, любой врач, который лечит болезнь, а не жалобы по определению хам. Так и живём
Ну и поскольку я сегодня добрый, я не буду напоминать про "К слову, физической памяти у твоего процесса никогда столько не будет". Хотя надо бы
Здравствуйте, Sinix, Вы писали:
I>>Похоже, кого то вопрос задел за живое. Так и говори — никак. S>Не угадал. Смысл повторять то, что уже отвечал, да ещё и без сарказма? Скучно же.
S>* используем buffer pool, выделяем из него сегменты, наворачиваем поверх коллекцию или stream, заполняем структурами. Vladek выше давал ссылку на RecyclableMemoryStream, там в документашке всё есть как бы. S>* других вариантов без unmanaged нет. Надо объяснять почему?
Ты лучше расскажи, как именно в buffer pool будет храниться миллиард строк. Мне непонятно, что значит "выделяем сегменты", "наворачиваем коллекции", "заполняем структурами"
Вот с серилизацией все понятно, всё само. А как в buffer pool ?
Здравствуйте, Ikemefula, Вы писали:
I>Ты лучше расскажи, как именно в buffer pool будет храниться миллиард строк. Мне непонятно, что значит "выделяем сегменты", "наворачиваем коллекции", "заполняем структурами"
Вот именно за этим я и отослал к книжке Бена Ватсона. Смысл обсуждать сложные вещи, если надо сперва пересказать азбуку оптимизации по хардкору?
Ну, т.е. любая попытка объяснения сведётся к тому, что сначала надо будет объяснять более базовые вещи и так до Рихтера.
I>Вот с серилизацией все понятно, всё само. А как в buffer pool ?
Смысл такой: у тебя есть возможность динамически аллоцировать/освобождать сегменты (массивы определённой длины) без создания дополнительной нагрузки на GC — освобождённые инстансы забираются обратно в пул. Количество этих сегментов — пока не исчерпается адресное пространство процесса / VM.
Всё, как их использовать — целиком и полностью на тебе.
На практике надо _очень_ хорошо понимать задачу, типовые сценарии и критерии по производительности. В общем, как и везде, хочешь выжать больше — будь готов жертвовать чем-то другим, например, простотой кода или универсальностью структур данных.
Здравствуйте, Albeoris, Вы писали:
A>Да я солидарен с тобой, поэтому предложил конкретное решение конкретной проблемы. Но когда деньги (потенциально, мои) начинают хранить в Doubla'ах, во мне просыпается кровожадное чудовище.
Оставайся человеком. A> Я понимаю, что всё это из области наколенных программ для домашнего использования, но однажды такие программисты придут в какой-нибудь "Сбербанк", и деньги со счетов тонкой струйкой потекут в тёплые страны. Не благодаря стечению обстоятельств, а по конкретному злому умыслу, эксплуатирующему уязвимость.
Не могут деньги со счетов потечь по этой причине. Если конечно в банковской бд не хранить суммы с точность превышающей копейки, если всегда округлять по одним правилам. Но это уже несколько о другом.
Здравствуйте, Sinix, Вы писали:
I>>Ты лучше расскажи, как именно в buffer pool будет храниться миллиард строк. Мне непонятно, что значит "выделяем сегменты", "наворачиваем коллекции", "заполняем структурами"
S>Вот именно за этим я и отослал к книжке Бена Ватсона. Смысл обсуждать сложные вещи, если надо сперва пересказать азбуку оптимизации по хардкору?
Ты сказал следующее "других вариантов без unmanaged нет". Вот я и думаю, как это относится к Pile ? Вот он умеет хранить миллиард строк.
S>Ну, т.е. любая попытка объяснения сведётся к тому, что сначала надо будет объяснять более базовые вещи и так до Рихтера.
Если что, я с товарищами несколько лет кряду оптимизировал приложение, где было конское количество объектов, до 100КК разных виртуальных вычислимых объектов. И это работало очень достойно, при чем в 32х бит приложении. Я правда не дошел до серилизатора и ММФ, думал слишком медленно будет. Однако, все сильно. Но вот интересно, как люди ухитряются тотально сбороть GC в миллиардах объектов.
S>Смысл такой: у тебя есть возможность динамически аллоцировать/освобождать сегменты (массивы определённой длины) без создания дополнительной нагрузки на GC — освобождённые инстансы забираются обратно в пул. Количество этих сегментов — пока не исчерпается адресное пространство процесса / VM.
Ок, наворачивать == аллоцировать/освобождать. Тогда строки хранить побайтно этих сегментах. В итоге получится тот же Pile, только менее универсальный, но более быстрый.
Насколько buffer pool будет быстре Pile ? Есть какие сравнения ?
Здравствуйте, pagid, Вы писали:
P>Не могут деньги со счетов потечь по этой причине. Если конечно в банковской бд не хранить суммы с точность превышающей копейки, если всегда округлять по одним правилам. Но это уже несколько о другом.
Если софтина дает гарантии корректной работы, то совершенно не важно, как всё хранится — синглом или децималом.
Проблема возникает тогда, когда люди пытаются делать "как правильно". Тогда с равной вероятностью надо ожидать проблем и от дабла и от децимала.
Здравствуйте, Ikemefula, Вы писали:
S>>Вот именно за этим я и отослал к книжке Бена Ватсона. Смысл обсуждать сложные вещи, если надо сперва пересказать азбуку оптимизации по хардкору? I>Ты сказал следующее "других вариантов без unmanaged нет". Вот я и думаю, как это относится к Pile ? Вот он умеет хранить миллиард строк.
Дык неэффективно же, через сериализацию. Вдобавок, сами сегменты хранятся как managed byte[] и по-прежнему создают нагрузку на GC.
Если уж и упарываться с "мы пойдём своим путём", то как-то так.
I>Если что, я с товарищами несколько лет кряду оптимизировал приложение, где было конское количество объектов, до 100КК разных виртуальных вычислимых объектов. И это работало очень достойно, при чем в 32х бит приложении. Я правда не дошел до серилизатора и ММФ, думал слишком медленно будет. Однако, все сильно. Но вот интересно, как люди ухитряются тотально сбороть GC в миллиардах объектов.
Нутуткак... с "мы не смогли в GC" возможны ровно два варианта:
1. Люди не читали матчасть, пока не стало поздно. За такими постами имеет смысл следить только ради "смотри, как делать не надо". Потому что если читать — подобные приседания за очень редкими исключениями не нужны. У вас же получилось
2. У людей реальный large scale и они на нём съели собаку. Как правило, таких постов не бывает, ибо NDA и не дураки дарить такой подарок конкурентам. Исключений очень мало, ссылки поприводил постом выше.
I>Ок, наворачивать == аллоцировать/освобождать. Тогда строки хранить побайтно этих сегментах. В итоге получится тот же Pile, только менее универсальный, но более быстрый. I>Насколько buffer pool будет быстре Pile ? Есть какие сравнения?
Сам по себе — одинаково. Выигрыш будет за счёт отсутствия сериализации (в обмен на заметное усложнение работы с произвольными структурами, да). Чтоб кто-то сравнивал — сомневаюсь, не настолько популярная тема, чтоб имело смысл бенчмарки лепить.
Здравствуйте, pagid, Вы писали:
P>Не могут деньги со счетов потечь по этой причине. Если конечно в банковской бд не хранить суммы с точность превышающей копейки, если всегда округлять по одним правилам. Но это уже несколько о другом.
Какие округления, человек?
Речь как раз о них. В банковских системах не округляют суммы и хранятся они с максимальной точностью (для чего и используется Decimal). Как только ты начинаешь округлять что либо, остаток остаётся "бесхозным". С точки зрения программиста, он просто отбросил лишнее. Но это "лишнее" имеет вполне материальное представление в твёрдой валюте, лежащей в сейфах. И вот когда об этом прознает достаточно умный и талантливый специалист, он сумеет вывести эти повисшие в воздухе остатки себе в карман. И если речь идёт о десятых долях копейки (цента, евроцента, и т.д.), то помноженные на миллионы запросов, они превращаются в мощный финансовый поток.
"Хаос всегда побеждает порядок, поскольку лучше организован." (с) Терри Пратчетт
Здравствуйте, Albeoris, Вы писали:
A>Какие округления, человек?
И с какой точностью ты видишь суммы в банковской выписке?
A>В банковских системах не округляют суммы
Это в какой стране так? господа, разработчики банковского софта, подскажите пожалуйста.
Если такое где-то есть, то там конечно возможны интересные эффекты.
A> и хранятся они с максимальной точностью (для чего и используется Decimal)
А памяти оперативной хватает, или как только разделишь $1 на 3 для обеспечения хранения одной суммы приходится приходится дисковые массивы использовать, их надеюсь хватает?
A> И вот когда об этом прознает достаточно умный и талантливый специалист, он сумеет вывести эти повисшие в воздухе остатки себе в карман. И если речь идёт о десятых долях копейки (цента, евроцента, и т.д.), то помноженные на миллионы запросов, они превращаются в мощный финансовый поток.
Детский сад.
Здравствуйте, Sinix, Вы писали:
S>Здравствуйте, Ikemefula, Вы писали:
S>>>Вот именно за этим я и отослал к книжке Бена Ватсона. Смысл обсуждать сложные вещи, если надо сперва пересказать азбуку оптимизации по хардкору? I>>Ты сказал следующее "других вариантов без unmanaged нет". Вот я и думаю, как это относится к Pile ? Вот он умеет хранить миллиард строк. S>Дык неэффективно же, через сериализацию. Вдобавок, сами сегменты хранятся как managed byte[] и по-прежнему создают нагрузку на GC.
Люди пишут, что при 80+ГБ объектов в памяти, на GC уходит ~15ms. Вполне нормально, имхо.
Всегда есть менее универсальное решение, которое будет быстрее. Суть в том, что этот Pile как раз претендует на универсальность засчёт некоторого снижения производительности. Если верить их тестам, то не на самой мощной машине там вполне приемлимый перформанс (~500K/sec write, 700K/sec read при объекте размером 75 байт) . Зато не надо подгонять данные под хранилище, что бывает достаточно важным в некоторых задачах.