Здравствуйте, alex_public, Вы писали:
_>Я же вроде там чётко написал что "не в исходнике". Так что речь грубо говоря о количестве процессорных инструкций затраченных на достижение одной и той же цели.
Это ни о чем. Нужна конкретная задача. Скажем тормозного джаваскрипта хватает для задач UI. Все твои эффективности в С++ дают нулевой выхлоп, если говорить про эту задачу. Или так — ядро проца выполняет около 5 млрд инструкций, а nginx почему то работает всего с 1024 коннектам на один поток.
Скажем в реалтайм процессинге проблемы уже давно не в скорости линейного кода, ибо полно реалтаймных приложений для всяких фондовых бирж которые работают джаве.
Вопрос так и остался открытым — где же будет та самая эффективность про которую ты говоришь.
I>>Для каких операций он не самый удобный ? для relational-like он практически самое лучше из того, что есть. ДЛя noSql он естесвенно не будет таким удобным, скажем для graph database нужна поддержка математики навроде bfs, dfs и тд. I>>Ты ошибочно понимаешь linq как мега универсальный подход. Он нужен для relational-like операций, данных и тд.
_>Нуу про нетабличные данные то я вообще молчу. ))) Но и для табличных "самое лучше что есть" звучит очень забавно, особенно с учётом того, что SQL создавался не для программистов.
Ну стало быть ты знаешь хороший способ, который гораздо лучше с этим справляется и при этом доступен как минимум всей аудитории C# девелоперов.
Теоретичеки можно заставить людей знать на раз теорию категорий и на этой основе строить апи для обработки данных. Реально это утопия, ибо теорию категорий знают единицы и следовательно такой способ недоступен всей аудитории.
Здравствуйте, Ikemefula, Вы писали:
I>Обработка IO completion уже займет порядка на три-четыре больше затрат.
Тебя обманули. Унутре там lock-free структуры, поэтому постановка задач в очередь в ядре почти бесплатная, а выгребать можно через GetQueuedCompletionStatusEx все накопившиеся задачи за раз и диспетчить их тоже забесплатно фактически. ТАм основная нагрузка собсно вызов ядерных ф-ий, поэтому уменьшение этих вызовов в пересчете на операцию дает буст.
I>Для сравнения, один поток в nginx обрабатывает всего 1024 соединения.
Сравнения с чем?
I>Обслуживание на async-await займет в худшем случае 1000-2000 тактов процессора. Это вообще ни о чем.
Это зависит от частоты событий. Раз в секунду — ни о чем... Под сотню тыщ раз в секунду — уже что-то.
I>Потому даже если С++ версия будет отрабатывать за 1 такт, то экономии нет и быть не может.
Смешно.
I>>>Кривая архитектура, это когда переходы непойми где делаются. А когда код легко майнтейнить, это хорошая архитектура. async упрощает майнтенанс. V>>Ну ты же как-то поддерживаешь обычный код? Тебя же не смущает, что переключение потоков в многопоточной ОС происходит "где-то" за пределами твоей программы? Тут аналогично. I>Да вот как то смущает ибо надо использовать всевозможные схемы синхронизации. А теперь ты хочешь получить на ровном месте еще одну такую же по сложности проблему.
Проще намного. Если несколько твоих фиберов лезут в одну и ту же переменную из одного и того же аппаратного потока, то никакая синхронизация не нужна. Ведь у нас на самом деле не неуправляемое переключение "потоков", а детерминированное. Получить такие же гарантии на async/await нереально. )) В общем случае нет гарантии, из какого потока что вызывается.
Здравствуйте, Ikemefula, Вы писали:
V>>Без проблем использовать await без всякой надуманной асинхронщины по прямому назначению — для того, чтобы наплодить легковесных безстековых короутин для той самой кооперативной многозадачности. I>Можно и это неосновное назначение.
У трюка не может быть другого назначения, кроме его принципа действия. ))
Характерно, что в дотнете, из-за привязки к "назначению", один и тот же трюк сделали дважды: yield для коллекций и await для короутин. И то и то идентичные короутины на генерируемом автомате с той разницей, что в последнем случае await равен yield, возвращающему void.
Ну и с вложением енумераторов у исходного yield не ахти, зато await это умеет изкаробки. Вот и вся разница. Тупо, не правда ли? Как я вижу на этом форуме, вводит хомячков в дикое заблуждение.
V>>Ну и названия ключевых слов вводят тебя в заблуждение настолько, что такое заблуждение преодолеть фактически нереально. ))) I>Я собтсвенно говорил про разницу между двумя вещами.
Если ты действительно это говорил, то ты споришь сам с собой уже. Короутины из буста и async/await — это похожие инструменты, даже работают практически одинаково за тем исключением, что в async/await потоки исполнения не настоящие, а эмулируемые через конечные автоматы.
V>>Ну так ты хвалишь заведомо более слабый инструмент, обвиняя более сильный в том, что это "просто кооперативная многозадачность". На C# async/await можно сэмулировать почти такую же. Только хуже. ))) I>Кооперативная многозадачность в чистом виде нужна чуть менее чем никогда.
Разве? )))
Как раз диспетчеризация событий в одном потоке на некоем completion port — это кооперативная многозадачность в незамутненном чистом виде. Про GUI loop даже и упоминать нелепо, ты сам его раз 100 упомянул уже.
Здравствуйте, vdimas, Вы писали:
V>Тебя обманули. Унутре там lock-free структуры, поэтому постановка задач в очередь в ядре почти бесплатная, а выгребать можно через GetQueuedCompletionStatusEx все накопившиеся задачи за раз и диспетчить их тоже забесплатно фактически. ТАм основная нагрузка собсно вызов ядерных ф-ий, поэтому уменьшение этих вызовов в пересчете на операцию дает буст.
И все это бесплатное почемуто может выдать только 1024 коннекта, ага.
I>>Для сравнения, один поток в nginx обрабатывает всего 1024 соединения. V>Сравнения с чем?
С издержками на async/await.
I>>Обслуживание на async-await займет в худшем случае 1000-2000 тактов процессора. Это вообще ни о чем. V>Это зависит от частоты событий. Раз в секунду — ни о чем... Под сотню тыщ раз в секунду — уже что-то.
Даже так это <5% от того, что может одно ядро.
I>>Потому даже если С++ версия будет отрабатывать за 1 такт, то экономии нет и быть не может. V>Смешно.
V>Проще намного. Если несколько твоих фиберов лезут в одну и ту же переменную из одного и того же аппаратного потока, то никакая синхронизация не нужна. Ведь у нас на самом деле не неуправляемое переключение "потоков", а детерминированное.
Гонки, голодание никуда не деваются. Все как было, так и осталось. Не ясно, как ты дашь какие то гарантии.
>Получить такие же гарантии на async/await нереально. )) В общем случае нет гарантии, из какого потока что вызывается.
Здравствуйте, vdimas, Вы писали:
V>>>Без проблем использовать await без всякой надуманной асинхронщины по прямому назначению — для того, чтобы наплодить легковесных безстековых короутин для той самой кооперативной многозадачности. I>>Можно и это неосновное назначение.
V>У трюка не может быть другого назначения, кроме его принципа действия. ))
Ты путаешь короутину с конкретным вариантом её использования. Скажем унутре это гораздо больше похоже на continuation.
V>Характерно, что в дотнете, из-за привязки к "назначению", один и тот же трюк сделали дважды: yield для коллекций и await для короутин. И то и то идентичные короутины на генерируемом автомате с той разницей, что в последнем случае await равен yield, возвращающему void.
yield и есть короутины, это никакие не коллекции. await — это уже решение для асинхронщины.
V>Если ты действительно это говорил, то ты споришь сам с собой уже. Короутины из буста и async/await — это похожие инструменты, даже работают практически одинаково за тем исключением, что в async/await потоки исполнения не настоящие, а эмулируемые через конечные автоматы.
Спасибо, капитан, скажи наконец уже хоть что нибудь, чего я до твоего пришествия не повторил хотя бы дважды.
I>>Кооперативная многозадачность в чистом виде нужна чуть менее чем никогда.
V>Разве? ))) V>Как раз диспетчеризация событий в одном потоке на некоем completion port — это кооперативная многозадачность в незамутненном чистом виде. Про GUI loop даже и упоминать нелепо, ты сам его раз 100 упомянул уже.
И практически все нативные реализации которые используют completion port не используют короутины.
Здравствуйте, Ikemefula, Вы писали:
V>>Входит, ес-но, но поддержка её ср-вами языка — нет. I>И в С++, что характерно, точно так же — скажем те же короутины буста сделаны самым честным хаком.
Язык позволяет. ))
V>>Да никак. Обычно вызывай и все. Это именно настоящее "выпрямление" кода. Легковесная многозадачность, где ВНУТРИ метода стоят хинты, когда переключать задачу, как в виндах 3.x. I>Ну ка, подробнее, что же за фокус такой, ты ни много ни мало утверждаешь, функция вдруг сама узнает, ожидаю ли я её результат и в зависимости от этого решит как делать процессинг ?
Какая ф-ий что узнает? Там просто в теле ф-ии есть хинты, когда забирать у фибера ресурсы и отдавать следующему. Или у тебя вопрос про шедуллинг, т.е. вопрос про управление очередью фиберов? Шедуллинг делается на уровне задач, требующих ожидания, т.е. на уровне поддержки задач ввода-вывода. Остальное пляшет оттуда. Собсно, кооперативная многозадачность на операция ввода-вывода в Win 3.x тому пример.
V>>С т.з. вызывающего метода это обычный синхронный код, а вся асинхронность сугубо внешняя, как внешим является переключение потоков ОС по отношению к обычному коду на C#. I>То есть, все функции будут синхронными с т.з. вызывающего кода, что внезапно останавливает message pump.
Оп-па...
Твой message pump вызывает не ф-ии, а короутины, т.е. передает управление потокам. Это не есть вызов ф-ии.
V>>Да. Программы для виндов 3.х прекрасно работали на win95, но уже с нормальной многозадачностью. I>Не понял идею. Речь про изменения в языке и использование этих изменений во фремворках. Или винда вдруг стала каким то языком ?
Да нет. Просто те же самые проги, которые раньше работали на основе кооперативной ОС, прекрасно работают в многозадачной. Сейчас ты работаешь в многозадачной, и у тебя проблем с поддержкой обычного кода нет. Вот и в "многозадачной ОС" проблем не было, если не делать 10 GOTO 10.
I>см "функция вдруг сама узнает, ожидаю ли я её результат"
Смотрел. Улыбнуло. Ф-ия должна делать некий yield next (твой await), если текущее состояние внешнего мира вынуждает её крутиться в 10 GOTO 10. А подробности этого "кручения" зависят от низлежащей ОС, от предоставляемых ср-в сигнализации готовности ввода/вывода.
Т.е., конечно должен быть набор библиотек IO, на основекоторых написан твой код. Все эти подробности с yield next должны быть упрятаны в эти либы, а твой прикладной код будет уже как простой линейный код.
V>>Дык, async еще более не нужен хотя бы потому, что на порядки менее удобный. I>"функция вдруг сама узнает, ожидаю ли я её результат"
Я уже понял, что ты ничего не понял.)
V>>Но с ней в С++ всегда было лучше, чем в других ООП языках, именно из-за многообразия функциональных типов и именно из-за того, что вся асинхронщина, которая "в лоб" (без asyc), идет как IoC, в котором функциональный подход заруливает ООП. А с короутинами еще проще...
I>Надо понимать async/await появились как ответ на одскульную асинхронщину.
Ес-но. Так же как подобные либы на плюсах задолго до. (а их полно)
Просто язык позволяет делать многое в рамках всё того же самого языка.
Здравствуйте, Ikemefula, Вы писали:
I>>>Для сравнения, один поток в nginx обрабатывает всего 1024 соединения. V>>Сравнения с чем? I>С издержками на async/await.
Нашел с чем сравнить.
I>>>Обслуживание на async-await займет в худшем случае 1000-2000 тактов процессора. Это вообще ни о чем. V>>Это зависит от частоты событий. Раз в секунду — ни о чем... Под сотню тыщ раз в секунду — уже что-то.
I>Даже так это <5% от того, что может одно ядро.
Да не все так просто. Дело не только в кол-ве тактов, но и в проходах по памяти. В async/await мы имеем графы наверченных друг на друга автоматов в куче и проход по этому графу при каждом шаге. Лишние косвенности каждый раз, а косвенность по внешней памяти обычно стоит намного больше тактов.
V>>Проще намного. Если несколько твоих фиберов лезут в одну и ту же переменную из одного и того же аппаратного потока, то никакая синхронизация не нужна. Ведь у нас на самом деле не неуправляемое переключение "потоков", а детерминированное. I>Гонки, голодание никуда не деваются. Все как было, так и осталось. Не ясно, как ты дашь какие то гарантии.
При отсутствии конкуренции за ресурсы нет ни гонок, ни голоданий.
>>Получить такие же гарантии на async/await нереально. )) В общем случае нет гарантии, из какого потока что вызывается. I>Как и в С++
Дудки. В С++ ты управляешь ситуацией — располагай легкие потоки в аппаратных как угодно. Т.е. ты имеешь возможность решать прикладные задачи через свою диспетчеризацию.
Здравствуйте, Ikemefula, Вы писали:
I>Это ни о чем. Нужна конкретная задача. Скажем тормозного джаваскрипта хватает для задач UI. Все твои эффективности в С++ дают нулевой выхлоп, если говорить про эту задачу. Или так — ядро проца выполняет около 5 млрд инструкций, а nginx почему то работает всего с 1024 коннектам на один поток. I>Скажем в реалтайм процессинге проблемы уже давно не в скорости линейного кода, ибо полно реалтаймных приложений для всяких фондовых бирж которые работают джаве. I>Вопрос так и остался открытым — где же будет та самая эффективность про которую ты говоришь.
Так я же тебе уже говорил, что если бы эта эффективность чего-то нам стоила (например каких-то дополнительных усилий при написание кода), то тогда имело бы смысл рассматривать конкретные задачи и в каждом частном случае считать есть ли смысл для подобной оптимизации или нет.
Но если мы получаем отсутствие накладных расходов на халяву (просто работая в обычном стиле) то это в любом случае и есть настоящая эффективность. )))
I>Ну стало быть ты знаешь хороший способ, который гораздо лучше с этим справляется и при этом доступен как минимум всей аудитории C# девелоперов. I>Теоретичеки можно заставить людей знать на раз теорию категорий и на этой основе строить апи для обработки данных. Реально это утопия, ибо теорию категорий знают единицы и следовательно такой способ недоступен всей аудитории.
Ээээ ну с таким подходом то я не буду спорить... Тут всё правильно. Но изначально у нас же был тезис об абсолютной "крутизне" linq, без привязки к C#, анализа уровня разработчиков и т.п.
Здравствуйте, alex_public, Вы писали:
_>Так я же тебе уже говорил, что если бы эта эффективность чего-то нам стоила (например каких-то дополнительных усилий при написание кода), то тогда имело бы смысл рассматривать конкретные задачи и в каждом частном случае считать есть ли смысл для подобной оптимизации или нет.
Халява в данном случае это ручная диспетчеризация и ручной контроль. Когда это нужно для оптимизации — это нормально. А как правило проблемы создает 10-20% кода, за это надо платить тем, что остальные 80-90% кода будет контролировать руками, даже если тебе это не хочется.
_>Но если мы получаем отсутствие накладных расходов на халяву (просто работая в обычном стиле) то это в любом случае и есть настоящая эффективность. )))
Это не эффективность а баловство. Любые оптимизации вне узкого места как минимум лишние, как максимум — создают проблемы на ровном месте.
_>Ээээ ну с таким подходом то я не буду спорить... Тут всё правильно.
Здравствуйте, vdimas, Вы писали:
V>>>Сравнения с чем? I>>С издержками на async/await.
V>Нашел с чем сравнить.
А что, сравнивать с синтетикой, навроде getline ?
I>>Даже так это <5% от того, что может одно ядро.
V>Да не все так просто. Дело не только в кол-ве тактов, но и в проходах по памяти. В async/await мы имеем графы наверченных друг на друга автоматов в куче и проход по этому графу при каждом шаге. Лишние косвенности каждый раз, а косвенность по внешней памяти обычно стоит намного больше тактов.
Это все теория. А на практике один лишь переход в ядро и обратно даст столько такто, что покроет минимум десять таких проходв.
I>>Гонки, голодание никуда не деваются. Все как было, так и осталось. Не ясно, как ты дашь какие то гарантии.
V>При отсутствии конкуренции за ресурсы нет ни гонок, ни голоданий.
Спасибо, капитан ! Похоже это новая концепция в многозадачном программировании.
А вот мне кажется, что проблемы уже могут быть в случае с тремя короутинами, каждая из которых готовит данные для другой.
I>>Как и в С++
V>Дудки. В С++ ты управляешь ситуацией — располагай легкие потоки в аппаратных как угодно. Т.е. ты имеешь возможность решать прикладные задачи через свою диспетчеризацию.
И это гарантирует что проблем с многозадачностью не будет ? Это слишком сильно сказано, что бы принимать без доказательства. Вот простой пример — три короутины, каждая готовит данные для одной из двух других, эдакое колечко. Нарушаешь порядок — получаешь проблемы. Но похоже твоя концепция как то гарантирует невозможность такой ситуации.
Здравствуйте, vdimas, Вы писали:
I>>Ну ка, подробнее, что же за фокус такой, ты ни много ни мало утверждаешь, функция вдруг сама узнает, ожидаю ли я её результат и в зависимости от этого решит как делать процессинг ?
V>Какая ф-ий что узнает? Там просто в теле ф-ии есть хинты, когда забирать у фибера ресурсы и отдавать следующему. Или у тебя вопрос про шедуллинг, т.е. вопрос про управление очередью фиберов? Шедуллинг делается на уровне задач, требующих ожидания, т.е. на уровне поддержки задач ввода-вывода. Остальное пляшет оттуда. Собсно, кооперативная многозадачность на операция ввода-вывода в Win 3.x тому пример.
И что же это за хинты унутре такие, которые подскажут функции, как она вызвана ? Не иначе сканирование назад по стеку и анализ на предмет вызова функции ожидания.
С async все ясно — можно вызывать с ожиданием, можно без ожидания. А как быть с твоими мега-функциями ?
V>>>С т.з. вызывающего метода это обычный синхронный код, а вся асинхронность сугубо внешняя, как внешим является переключение потоков ОС по отношению к обычному коду на C#. I>>То есть, все функции будут синхронными с т.з. вызывающего кода, что внезапно останавливает message pump.
V>Оп-па... V>Твой message pump вызывает не ф-ии, а короутины, т.е. передает управление потокам. Это не есть вызов ф-ии.
V>>>Да. Программы для виндов 3.х прекрасно работали на win95, но уже с нормальной многозадачностью. I>>Не понял идею. Речь про изменения в языке и использование этих изменений во фремворках. Или винда вдруг стала каким то языком ?
V>Да нет. Просто те же самые проги, которые раньше работали на основе кооперативной ОС, прекрасно работают в многозадачной. Сейчас ты работаешь в многозадачной, и у тебя проблем с поддержкой обычного кода нет. Вот и в "многозадачной ОС" проблем не было, если не делать 10 GOTO 10.
I>>см "функция вдруг сама узнает, ожидаю ли я её результат"
V>Смотрел. Улыбнуло. Ф-ия должна делать некий yield next (твой await), если текущее состояние внешнего мира вынуждает её крутиться в 10 GOTO 10. А подробности этого "кручения" зависят от низлежащей ОС, от предоставляемых ср-в сигнализации готовности ввода/вывода.
V>Т.е., конечно должен быть набор библиотек IO, на основекоторых написан твой код. Все эти подробности с yield next должны быть упрятаны в эти либы, а твой прикладной код будет уже как простой линейный код.
V>>>Дык, async еще более не нужен хотя бы потому, что на порядки менее удобный. I>>"функция вдруг сама узнает, ожидаю ли я её результат"
V>Я уже понял, что ты ничего не понял.)
V>>>Но с ней в С++ всегда было лучше, чем в других ООП языках, именно из-за многообразия функциональных типов и именно из-за того, что вся асинхронщина, которая "в лоб" (без asyc), идет как IoC, в котором функциональный подход заруливает ООП. А с короутинами еще проще...
I>>Надо понимать async/await появились как ответ на одскульную асинхронщину.
V>Ес-но. Так же как подобные либы на плюсах задолго до. (а их полно) V>Просто язык позволяет делать многое в рамках всё того же самого языка.
Здравствуйте, Ikemefula, Вы писали:
V>>Нашел с чем сравнить. I>А что, сравнивать с синтетикой, навроде getline ?
Вообще-то, да, с синтетикой. Если сравниваются голые затраты механизма диспетчеризации событий.
V>>Да не все так просто. Дело не только в кол-ве тактов, но и в проходах по памяти. В async/await мы имеем графы наверченных друг на друга автоматов в куче и проход по этому графу при каждом шаге. Лишние косвенности каждый раз, а косвенность по внешней памяти обычно стоит намного больше тактов. I>Это все теория. А на практике один лишь переход в ядро и обратно даст столько такто, что покроет минимум десять таких проходв.
Не каждый ядерный вызов тяжел. Стоимость голой SYSENTER не так уж высока.
V>>При отсутствии конкуренции за ресурсы нет ни гонок, ни голоданий. I>Спасибо, капитан ! Похоже это новая концепция в многозадачном программировании.
Ну гонок при описанном сценарии избегаем в любом случае. А голодание лечится завязкой шедуллинга на состояние прикладных данных.
I>А вот мне кажется, что проблемы уже могут быть в случае с тремя короутинами, каждая из которых готовит данные для другой.
Простейшая автовыравнивание нагрузки — взаимная очередь фиксированного сверху размера, блокируемая для кода короутины, если очередь полна при записи или пуста при чтении. Но есть и еще более динамичные варианты, например, на основе некоей информации по обратной связи. Можно сэмулировать простейший фильтр 1-го порядка по обратной связи по информации о текущей длине очереди, по его показаниям фибер-производитель может назначать себе "штрафы".
I>И это гарантирует что проблем с многозадачностью не будет ? Это слишком сильно сказано, что бы принимать без доказательства. Вот простой пример — три короутины, каждая готовит данные для одной из двух других, эдакое колечко. Нарушаешь порядок — получаешь проблемы. Но похоже твоя концепция как то гарантирует невозможность такой ситуации.
У каждой короутины доложен быть некий сигнал готовности, чтобы она не получала управление для "холостого" оборота. В чем будет заключаться этот сигнал — сугубо прикладная хрень.
I>>>Ну ка, подробнее, что же за фокус такой, ты ни много ни мало утверждаешь, функция вдруг сама узнает, ожидаю ли я её результат и в зависимости от этого решит как делать процессинг ?
V>>Какая ф-ий что узнает? Там просто в теле ф-ии есть хинты, когда забирать у фибера ресурсы и отдавать следующему. Или у тебя вопрос про шедуллинг, т.е. вопрос про управление очередью фиберов? Шедуллинг делается на уровне задач, требующих ожидания, т.е. на уровне поддержки задач ввода-вывода. Остальное пляшет оттуда. Собсно, кооперативная многозадачность на операция ввода-вывода в Win 3.x тому пример.
I>И что же это за хинты унутре такие, которые подскажут функции, как она вызвана ? Не иначе сканирование назад по стеку и анализ на предмет вызова функции ожидания.
Ты опять путаешь вызов ф-ии внутри короутины и передачу управления самой короутине.
I>С async все ясно — можно вызывать с ожиданием, можно без ожидания. А как быть с твоими мега-функциями ?
Должен быть сформирован сам фибер изначально, который будет запущен на исполнение. Код внутри него всегда с ожиданием, т.е. синхронный.
Здравствуйте, vdimas, Вы писали:
I>>И что же это за хинты унутре такие, которые подскажут функции, как она вызвана ? Не иначе сканирование назад по стеку и анализ на предмет вызова функции ожидания.
V>Ты опять путаешь вызов ф-ии внутри короутины и передачу управления самой короутине.
Не я, а ты. Ожидание возникает не от того, какие у тебя функции, а от того, когда нужно делать вызов и когда ожидать данных. Как ты чего вызываешь не имеет никакого значения. Если задача требует блокировки — надо делать ожидание. Если задача требует неблокирующий вызов — надо делать именно такой.
Покажи аналог для каждой из строчек
await X();
X();
>>С async все ясно — можно вызывать с ожиданием, можно без ожидания. А как быть с твоими мега-функциями ?
V>Должен быть сформирован сам фибер изначально, который будет запущен на исполнение. Код внутри него всегда с ожиданием, т.е. синхронный.
Здравствуйте, Ikemefula, Вы писали:
I>Халява в данном случае это ручная диспетчеризация и ручной контроль. Когда это нужно для оптимизации — это нормально. А как правило проблемы создает 10-20% кода, за это надо платить тем, что остальные 80-90% кода будет контролировать руками, даже если тебе это не хочется.
Какая ещё ручная диспетчеризация и ручной контроль? ) Мы же вроде бы уже давно договорились что C++ вариант внешне отличается от C# варианта только тем что там макросы (которые пишутся один раз вообще).
I>Это не эффективность а баловство. Любые оптимизации вне узкого места как минимум лишние, как максимум — создают проблемы на ровном месте.
Т.е. если завтра компилятор C# каким-то чудом ускорят раза в два, то ты скажешь "извините, но я возможно не буду этим пользоваться, т.к. я ещё не замерил есть ли у меня узкие места в моём ПО или нет"? )))
I>!!!
Ну так никто и не спорил что linq — это прорыв внутри C#. Это факт естественно. Просто некоторые странные личности иногда начинают говорить что это прорыв не внутри C#, а вообще в программирование (типа как концепция) — вот это конечно вызывает только смех. )))
Здравствуйте, vdimas, Вы писали:
V>>>Нашел с чем сравнить. I>>А что, сравнивать с синтетикой, навроде getline ?
V>Вообще-то, да, с синтетикой. Если сравниваются голые затраты механизма диспетчеризации событий.
Это никому не интересно. Скажем, это не дает объяснения, почему веб-приложения массово пишутся на менеджед платформах, хотя казалось бы, они вечно испытывают нехватку ресусорв, памяти, процессора и тд и тд.
Если смотреть синтетику, то веб-приложения должны писаться на С++. А вот десктоп приложения, где вагон ресурсов, почему то до сих пор частенько пишутся на С++, хотя я бы не сказал что в большинстве случаев. Казалось бы — должно быть наоборот. Ан нет.
А если глянуть на реальные задачи, стновится понятно, где чего экономится. Скажем ручное управление памятью в веб-приложении задача адски сложная и неудивительно, что GC справляется гораздо лучше -> managed. Цена низкоуровневой оптимизации в таких задачах слишком высока, потому весь функционал предельно упрощен. А в десктопе все проще — ресурсов в пересчете на задачу больше + есть вещи, которые требуют перформанс. Вот здесь ручные оптимизации вводить достаточно легко и цена таких изменений сравнительно мала, отсюда ясно, что для десктопа все еще актуально писать на С++.
Реалтайм приложения, что характерно, требуют в первую очередь корретной работы с ресурсами, низкоуровневый перформанс дело второстепенное. Отсюда понятно, почему приложения для биржи и тд, пишутся в т.ч. на Джаве той же.
Есть другие случаи, скажем серверные приложения которые требуют достаточно высокий перформанс в задачах, которые упираются в низкоуровневый перформанс, такие невозможно решить в менеджед — обработка звука, видео, изображений. Менеджед применяется очень осторожно и всегда вместе с нативными библиотеками. Скажем, никто в своем уме не будет заниматься обработкой видео на C# или Джаве. И даже в этом случае цветут и пахнут гибридные приложения.
I>>Это все теория. А на практике один лишь переход в ядро и обратно даст столько такто, что покроет минимум десять таких проходв.
V>Не каждый ядерный вызов тяжел. Стоимость голой SYSENTER не так уж высока.
Давай ближе к конкретному примеру.
I>>Спасибо, капитан ! Похоже это новая концепция в многозадачном программировании.
V>Ну гонок при описанном сценарии избегаем в любом случае. А голодание лечится завязкой шедуллинга на состояние прикладных данных.
"Вот простой пример — три короутины, каждая готовит данные для одной из двух других, эдакое колечко. Нарушаешь порядок — получаешь проблемы."
I>>А вот мне кажется, что проблемы уже могут быть в случае с тремя короутинами, каждая из которых готовит данные для другой.
V>Простейшая автовыравнивание нагрузки — взаимная очередь фиксированного сверху размера, блокируемая для кода короутины, если очередь полна при записи или пуста при чтении. Но есть и еще более динамичные варианты, например, на основе некоей информации по обратной связи. Можно сэмулировать простейший фильтр 1-го порядка по обратной связи по информации о текущей длине очереди, по его показаниям фибер-производитель может назначать себе "штрафы".
Вот так время процессора начинает расходоваться непойми на что.
I>>И это гарантирует что проблем с многозадачностью не будет ? Это слишком сильно сказано, что бы принимать без доказательства. Вот простой пример — три короутины, каждая готовит данные для одной из двух других, эдакое колечко. Нарушаешь порядок — получаешь проблемы. Но похоже твоя концепция как то гарантирует невозможность такой ситуации.
V>У каждой короутины доложен быть некий сигнал готовности, чтобы она не получала управление для "холостого" оборота. В чем будет заключаться этот сигнал — сугубо прикладная хрень.
То есть, гарантий никаких, что и требовалось доказать, все конфликты надо разруливать руками, руками и еще раз руками.
Здравствуйте, alex_public, Вы писали:
I>>Халява в данном случае это ручная диспетчеризация и ручной контроль. Когда это нужно для оптимизации — это нормально. А как правило проблемы создает 10-20% кода, за это надо платить тем, что остальные 80-90% кода будет контролировать руками, даже если тебе это не хочется.
_>Какая ещё ручная диспетчеризация и ручной контроль? ) Мы же вроде бы уже давно договорились что C++ вариант внешне отличается от C# варианта только тем что там макросы (которые пишутся один раз вообще).
Это теоретически. Для случаев посложнее надо пилить или макросы посложнее или расширять фремворк или колбасить все вручную.
I>>Это не эффективность а баловство. Любые оптимизации вне узкого места как минимум лишние, как максимум — создают проблемы на ровном месте.
_>Т.е. если завтра компилятор C# каким-то чудом ускорят раза в два, то ты скажешь "извините, но я возможно не буду этим пользоваться, т.к. я ещё не замерил есть ли у меня узкие места в моём ПО или нет"? )))
Скорость компиляции является узким местом в средствах разработки. Полноценная навигация, интеллисенс, юнит тесты и прочие вкусности IDE невозможны без быстрого компилятора. Никто не будет пускать юнит-тесты, если проект надо компилировать по сорок минут.
Здравствуйте, Ikemefula, Вы писали:
I>Это никому не интересно. Скажем, это не дает объяснения, почему веб-приложения массово пишутся на менеджед платформах, хотя казалось бы, они вечно испытывают нехватку ресусорв, памяти, процессора и тд и тд.
Уже же обсуждали это. Подавляющее чисто всех серверов и баз данных написаны на C/C++ и именно там происходят все критические нагрузки. А то, что ты называешь гордым именем "веб-приложения" — это всего лишь тончайшая скриптовая прослойка между вызовами функций веб-сервера и базы данных. И не удивительно что там лидируют всякие php — у него запредельная скорость написания и модификации кода (говнокода обычно ). Причём для последнего даже не нужны никакие перекомпиляции т.п.
Вот если бы у нас сами сервера и базы данных были написаны на управляемых платформах, то твои слова уже имели бы реальное обоснование....
Здравствуйте, Ikemefula, Вы писали:
I>Это теоретически. Для случаев посложнее надо пилить или макросы посложнее или расширять фремворк или колбасить все вручную.
Для каких ещё случаев посложнее? Представленное решение полностью повторяет всё поведение C# реализации. Всё, точка. Никакие модификации этих 20 строчек не требуются — оно работает в любых условиях, в которых работает C# вариант.
_>>Т.е. если завтра компилятор C# каким-то чудом ускорят раза в два, то ты скажешь "извините, но я возможно не буду этим пользоваться, т.к. я ещё не замерил есть ли у меня узкие места в моём ПО или нет"? ))) I>Скорость компиляции является узким местом в средствах разработки. Полноценная навигация, интеллисенс, юнит тесты и прочие вкусности IDE невозможны без быстрого компилятора. Никто не будет пускать юнит-тесты, если проект надо компилировать по сорок минут.
Имелось ввиду ускорение генерируемого кода, а не скорости компиляции. Я конечно мутно сказал там... )
Здравствуйте, AndrewVK, Вы писали:
V>>>>Но когда они вникают в подробности конкретного участка, поверь, их точно так же интересуют точные типы. AVK>>>Отучайся говорить за всех. Лично я первое, что делаю при ковырянии чужого кода — Full Cleanup, который, в числе прочего, заменяет все типы в декларациях на var. V>>Мало ли, что лично ты делаешь?
AVK>Тогда поясни — либо "их" это все таки несколько более узкий круг, чем заявлено, либо я не принадлежу к "более опытным разработчикам".
Угу, характерно, что упоминание конкретного примера, где точный тип обязателен, ты проигнорил...