Re[30]: Nemerle vs. C#. До сих пор привыкнуть не могу :)
От: VladD2 Российская Империя www.nemerle.org
Дата: 18.08.13 01:40
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>Похоже это хроническое заболевание у немерлистов, не могут прочесть, что речь про мой проект, это он заморожен.


А из каких слов можно вывести, что речь идет о каком-то своем проекте?

I>Я вижу кому то батхерт мешает прочитать уже в который раз.


Что прочитать то?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[31]: Nemerle vs. C#. До сих пор привыкнуть не могу :)
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 18.08.13 08:14
Оценка:
Здравствуйте, VladD2, Вы писали:


I>>Похоже это хроническое заболевание у немерлистов, не могут прочесть, что речь про мой проект, это он заморожен.


VD>А из каких слов можно вывести, что речь идет о каком-то своем проекте?


Если читать ветку, а не отдельные сообщения, то вполне понятно.

I>>Я вижу кому то батхерт мешает прочитать уже в который раз.


VD>Что прочитать то?


Сильное ощущение, что ты тыкаешь наобум в первое попавшееся сообщение и чтото пишешь.
Re[31]: Nemerle vs. C#. До сих пор привыкнуть не могу :)
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 18.08.13 08:17
Оценка: +1
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, Ikemefula, Вы писали:


I>>Такой уникальный подход к обсуждению проблем почему-то у проекта Немерле. Сколько ни переписывался с авторами других проектов, подход примерно такой "проблема-обсуждение" или "проблема-тикет-приоритет"


VD>А ты попробуй высосать проблему из пальца, как в данном случае. И не забудь упомянуть про фрагментацию LOH. Это важно.


Обчно люди сразу честно говорят — проблема есть, приоритет низкий, фиксить не будем и предлагают какие нибудь пути решения. А у тебя куда ни ткни, все время тот воркфлоу что указал, начинается с отрицания и заканчивается "сделай сам".
Re[27]: Nemerle vs. C#. До сих пор привыкнуть не могу :)
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 18.08.13 08:27
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Не странно, а полная чушь. Сборки грузятся в память как и любые другие ДЛЛ-и в Виндовс — по средствам отображаемых в память файлов. Сборки дотнета не что иное как обычный PE (Portable Executabl) файл виндовс. Возьми любую свою сборку и отправь на http://pedump.me. Сам это увидишь. За в какую область памяти грузится ДЛЛ отвечает параметр компиляции /baseaddress. Если его не задавать, то высока вероятность колизий между сборками. При этом все кроме первой сборки будут сдвигаться загрузчиком ОС. При сдвижке занимается память в процессе. Но это не менеджед-память, а обычныая (выделяемая ВиртуалАлоком). Если же задать для ДЛЛ-ей /baseaddress (можно задать в настройках проекта шарпа, например), то сборки будут проецироваться в память процесса и разделяться всеми процессами загружающими эту бсору. На объем доступного процессу адресного пространства это влиять не должно, так как не зависимо от того разделяется длл или нет они все равно занимает память.


Этими сведениями для менеджед сборок можно пренебречь.

I>>Сборка, по моему, лежит в GC Heap, код — в JIT Heap.


VD>Ранайм фрэймворка — это анменеджед код. Он не может пользоваться управляемыми хипами. Где и как лежит сборка я описал выше. Джит используют свою память, но ты можешь воспользоваться NGEN-ом. Образы полученные с помощью NGEN подгружаются в процесс точно так же как и любые другие длл-и — поецированием файлов в память.


А кто говорил про ngen ?

I>>Для GC, это просто хипы, как и LOH, Loader Heap, Fast, Slow, COM-Heap и тд и тд и тд.


VD>GC вообще ничего не знает о анменеджет-хипах.


Который из хипов выше анменеджед ?

I>>Сборками можно выюзать хоть всю память и при этом "Влиять на фрагментацию они не могут". Ты точно это хотел сказать ?\


VD>Ау! Меня не слышат? Сборки, ну, кроме динамически подгружаемых, грузятся во время старта процесса. В это время для них выделяется адресное пространство. Выделяется системными (виндовыми) средствами. Далее оно не меняется. Влиять на фрагментацию LOH они не могут.


Они как минимум уменьшают размер доступного АП. А что бы АП не расходовалась зря, сборки грузятся динамически. Странно, да ?

I>>Десятки, как минимум, мегабайт, вдруг стали килобайтами ? Ну-ну.


VD>Какие, на фиг, десятки мегабайт? Чтобы получить сборку в десяток мегабайт нужно написать код в десятки мегабайт. Да и десятки мегабайт по сравнению с гигабйтами доступной памяти в микроскоп не различимы.


Правильно, и снова видим, что ты не читатель, ибо я уже трижды указал что код исчисляется аккурат десятками мегабайт.


I>>Фрагментируется адрессное пространство. Сборки как раз уменьшают непрерывную область. А дальше хипы LOH кладутся как бог на душу положит.


VD>Внимание, вопрос. Если сборки грузятся практически одновременно во время загрузки приложения, то как они могу влиять на фрагментацию того, что занимается после этого?


"если" это ты притягиваешь за уши нужный тебе результат. Но вообще могут — картина распределения меняется и хипы GC и Loh распределяются совершенно иначе.

I>>Макросы вдруг стали выдавать более компактный код. Похоже, тут пахнет нобелевкой

VD>Похоже тут пахнет невежеством.

Вот-вот. Подумай над этим.

VD>>>Ну, и? Они превратятся в ~50 длл-и. Объем занимаемой ими памяти один хрен не будет определяться размером ДЛЛ-и, а будет определяться объемом хранимых в памяти данных.

I>>В том числе и размером самих ДЛЛ и размером генеренного джытом кода. Когда нужно большое окно в АП, все лишние помехи это фейл.

VD>В том числе будет 0.001%.


Это ты сильно заблуждаешься. Вопросами фрагментации и нюансами загрузки сборок и расходования памяти завален чуть не весь инет.

VD>И вообще, если у тебя проблемы с адресным пространством в 32-битном приложении, то перейди на 64-битный процесс или, если у тебя какие-то завязки на x86, задай при старте винды ключик позволяющий отдавать под пользовательские данные 3 гига и гиг будет в твоем распоряжении.


Спасибо, капитан(уже наверное майор). Такие решения уже отработаны.

I>>Давай вместе посмотрим, от кого здесь аргументы навроде "баттхёрт" и прочих вещей, включая намёки на квалификацию и тд и тд и тд ?


VD>Это не аргумент, а констатация факта. Чем-то тебе очень сильно задел, то ли Немерл, то ли я.


Правильно, констатация факта, пересмотри свои сообщения и забань виновного, как Кочетков
Re[52]: Nemerle vs. C#. До сих пор привыкнуть не могу :)
От: artelk  
Дата: 18.08.13 11:35
Оценка:
Здравствуйте, fddima, Вы писали:

F>Здравствуйте, artelk, Вы писали:


F>>>>>Делегат может быть быстрее.

A>>>>За счет чего?
F>>> За счет того, что никакого диспатчинга не происходит. Делегат — это this и массив готовых указателей на методы. Ну и их хорошенько оптимизировали в .net 2+, если память не изменяет.
A>>Work — невиртуальный метод, никакого диспатчинга нет.
F> Function.Invoke — виртуальный.

Я имел ввиду "за счет чего он может быть быстрее прямого вызова невиртуального Work?". Ну да и фиг с ним...
Re[53]: Nemerle vs. C#. До сих пор привыкнуть не могу :)
От: fddima  
Дата: 19.08.13 11:15
Оценка:
Здравствуйте, artelk, Вы писали:

A>Я имел ввиду "за счет чего он может быть быстрее прямого вызова невиртуального Work?". Ну да и фиг с ним...

Писал-писал сообщение и прошляпил его. В общем — мы просто недопоняли друг друга. Я конечно же имел ввиду, по сравнению с виртуальным конечно же, в контексте обсуждения — других у нас нет, а в тест незасматривался.
Instance Call — требует 1 обращение к памяти (проверка this на null)
Delegate Call — требует 2 обращения к памяти (загрузка this из делегата и косвенный вызов, проверка адреса делегата на null — достаётся бесплатно)
Virtual Call — требует 3 обращений (получение описателя типа из this, получение таблицы методов из описателя типа, косвенный вызов, проверка this на null — достаётся бесплатно)
Учитывая, что даже 3x накладые расходы толком то рассмотреть не получается даже в микроскоп (с помощью тех же тестов) — подозреваю, что основная стоимость вызова лежит в инструкциях call/jmp. Хотя для тех у кого узкое место — память и малый кеш — возможно разница будет ощутимее, хотя обычно в таких ситуациях бранчинг тоже не блещет.
Иногда, кстати, микробенчи показывают, что виртуальный вызов быстрее остальных в два раза (я такого легко добивался, перемещением кода циклов вверх-вниз относительно друг друга). Именно это и показывает несостоятельность подобного бенчмаркинга (в отрыве от задачи).
Re[53]: Nemerle vs. C#. До сих пор привыкнуть не могу :)
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.08.13 19:23
Оценка:
Здравствуйте, artelk, Вы писали:

A>Я имел ввиду "за счет чего он может быть быстрее прямого вызова невиртуального Work?". Ну да и фиг с ним...


Какой-то косяк в тесте. Исходные тесты имеют сразу несколько скользких мест. Я бы на них не обращал внимание. Не вертуальные примитивные метода вообще инлайнятся. Так что там измерять просто не чего.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[54]: Nemerle vs. C#. До сих пор привыкнуть не могу :)
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.08.13 19:38
Оценка:
Здравствуйте, fddima, Вы писали:

F> Delegate Call — требует 2 обращения к памяти (загрузка this из делегата и косвенный вызов, проверка адреса делегата на null — достаётся бесплатно)


Это очень поверхностная теория. Реально ссылка лежит на мультикаст-делегат. Это весма сложная штука. МС что-то там оптимизирует и (видимо) заменяет мультикаст на что-то другое. Это само по себе требует времени. Так что в случае вызова где делегат создается за нова — это отнюдь не дешево. Далее кэшируется все тоже не так просто (скорее всего) как ты говоришь.

Если хочешь разобраться, нужно декомпилять в ассемблер релизные машкоды и разбираться с ними. Причем делать это как в области создания делегата, так и в области вызова. Ну, и разные случаи рассматривать. Я вот тут рядом показывал как просаживается производительность делегатов когда делаешь делегат на обобщенный статический метод. Там явно какая-то хмия.

F> Virtual Call — требует 3 обращений (получение описателя типа из this, получение таблицы методов из описателя типа, косвенный вызов, проверка this на null — достаётся бесплатно)


Это точно не верно. Таблица методов получается из объекта непосредственно. А нужны метод просто ее индексированием. Так что это налогично доступу к неуправляемому массиву. А учитывая инструкции современных проецессоров и предсказание ветвления ими это можно зачесть за одну операцию (для Core+). Подробности здесь
Автор(ы): Чистяков Влад (VladD2)
Дата: 14.06.2006
Уже много сказано слов о том, что такое GC, чем он хорош и как лучше его применять. Но, наверно, очень многим хочется знать, как устроен конкретный GC. Данная статья открывает некоторые подробности устройчтва GC в .NET Framework.
.

F> Иногда, кстати, микробенчи показывают, что виртуальный вызов быстрее остальных в два раза (я такого легко добивался, перемещением кода циклов вверх-вниз относительно друг друга). Именно это и показывает несостоятельность подобного бенчмаркинга (в отрыве от задачи).


Зачем разбирать детали вызовов, если в итоге вывод на этом не строится?

В этом я с тобой полностью согласен. Чем синтетичнее тесты, тем меньше от них толку. Надо рать задачу и решать ее разными методами. Тогда и результат будет виден. При этом нужно умудриться и тесты корректно написать, и протестировать правильно. В общем, не простая задача с неопределенным результатом. Она только на первый взгляд выглядит просто.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[55]: Nemerle vs. C#. До сих пор привыкнуть не могу :)
От: fddima  
Дата: 19.08.13 20:47
Оценка:
Здравствуйте, VladD2, Вы писали:

F>> Delegate Call — требует 2 обращения к памяти (загрузка this из делегата и косвенный вызов, проверка адреса делегата на null — достаётся бесплатно)

VD>Это очень поверхностная теория. Реально ссылка лежит на мультикаст-делегат. Это весма сложная штука. МС что-то там оптимизирует и (видимо) заменяет мультикаст на что-то другое. Это само по себе требует времени. Так что в случае вызова где делегат создается за нова — это отнюдь не дешево. Далее кэшируется все тоже не так просто (скорее всего) как ты говоришь.
Понятно что в целом оно поверхностно. Но конкретно это вроде как и не поверхностная теория. Там (внутри мультикаст делегата) лежит this и адрес метода который вызывается готовым кодом. Буквально две инструкции на ассемблере. Да, CLR использует fastcall для вызова методов, а не магию.
Соотв., если это single-cast — достаточно в адрес положить реально адрес метода, который указывает делегат.
Если multi-cast — тогда он указывает на некий трамплин, который сделает всё грязное дело.
Суть в том, что заточка под single-cast она действительно есть, но она — очень простая на самом деле и по своей сути.

VD>Если хочешь разобраться, нужно декомпилять в ассемблер релизные машкоды и разбираться с ними. Причем делать это как в области создания делегата, так и в области вызова. Ну, и разные случаи рассматривать. Я вот тут рядом показывал как просаживается производительность делегатов когда делаешь делегат на обобщенный статический метод. Там явно какая-то хмия.

Создание делегата на джерениках — намного медленнее — это вроде как давно известная штука. Я не буду строить догадок — мне неинтересно это. В добавок тут я уже упоминал, что не факт что создание делегатов vs классов-функторов будет быстрее. Я не знаю как это проверить, а чистая теория именно про этот момент — не интересна.

VD>Это точно не верно. Таблица методов получается из объекта непосредственно. А нужны метод просто ее индексированием. Так что это налогично доступу к неуправляемому массиву. А учитывая инструкции современных проецессоров и предсказание ветвления ими это можно зачесть за одну операцию (для Core+). Подробности здесь
Автор(ы): Чистяков Влад (VladD2)
Дата: 14.06.2006
Уже много сказано слов о том, что такое GC, чем он хорош и как лучше его применять. Но, наверно, очень многим хочется знать, как устроен конкретный GC. Данная статья открывает некоторые подробности устройчтва GC в .NET Framework.
.

Да... Смотрел как раз и на дизассемблер, и документацию, и жестоко затупил. Спасибо.
Ну тогда получается ещё лучше — и виртуальный вызов и делегат — оба потребуют только двойную косвенность. Хотя в случае с делегатом — там чтение из одной линейки кеша скорее всего происходит (по адресам — два поля рядышком).

F>> Иногда, кстати, микробенчи показывают, что виртуальный вызов быстрее остальных в два раза (я такого легко добивался, перемещением кода циклов вверх-вниз относительно друг друга). Именно это и показывает несостоятельность подобного бенчмаркинга (в отрыве от задачи).

VD>Зачем разбирать детали вызовов, если в итоге вывод на этом не строится?
Нет, это значит, что стоимость вызовов — существует, они не бесплатны. Но простыми циклами мы её никак за хвост не схватим. Я описанное наблюдал на бенчмарке не приведенном здесь, но суть приблизительно та же — т.е. в топку.
Re[56]: Nemerle vs. C#. До сих пор привыкнуть не могу :)
От: VladD2 Российская Империя www.nemerle.org
Дата: 20.08.13 19:51
Оценка:
Здравствуйте, fddima, Вы писали:

F> Создание делегата на джерениках — намного медленнее — это вроде как давно известная штука. Я не буду строить догадок — мне неинтересно это. В добавок тут я уже упоминал, что не факт что создание делегатов vs классов-функторов будет быстрее. Я не знаю как это проверить, а чистая теория именно про этот момент — не интересна.


Я тут рядом тест проводил. У Немерла статические дженерик-методы проблем с производительностью не вызывают. Как раз из-за того, что всегда класс для лямбд генерируется. А он уже вызывает статический метод оптимально.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.