Здравствуйте, rg45, Вы писали:
R>Ты никогда не сталкивался с тем, что картинка в профиляторе может разительно изменяться при переключении между дебагом и релизом?
Разумеется. Поэтому и приходится выяснять особенности кодогенерации и работы отладочных библиотек, чтобы она изменялась не "разительно", а более-менее управляемо, и отладочный код мог работать с нужной скоростью в реальном времени.
Здравствуйте, rg45, Вы писали:
ЕМ>>С чего бы вдруг? Если код не написан настолько топорно, что многоуровневые циклы при оптимизации сворачиваются в линейную формулу, из часто вызываемых мелких функций не выбрасываются развесистые записи в лог, или что-нибудь вроде этого, то включение оптимизации не ускоряет код на порядки, и в основном соотношение затрат между разными частями кода остается примерно таким же. А если отладочный режим еще и управляется не по "да-нет", а хотя бы по нескольким основным параметрам (проверки типов/индексов, проверки инвариантов, проверки целостности объектов, подробность лога и т.п.), то и вовсе нет проблем.
R>Ты никогда не сталкивался с тем, что картинка в профиляторе может разительно изменяться при переключении между дебагом и релизом?
В его задачах по три-четыре массива примитивных типов (вроде uint8_t, uint16_t или uint32_t) и относительно несложная математика при перекладывании данных из одного массива в другой.
И с этими же представлениями он судит о цепочках вызовов в 10-15 уровней в глубину сквозь 3-4 слоя абстракции.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Разумеется. Поэтому и приходится выяснять особенности кодогенерации и работы отладочных библиотек, чтобы она изменялась не "разительно", а более-менее управляемо, и отладочный код мог работать с нужной скоростью в реальном времени.
Каким образом определяется "нужная скорость" для отладочного режима и какими методами она достигается?
Здравствуйте, rg45, Вы писали:
R>Каким образом определяется "нужная скорость" для отладочного режима
Как обычно — чтобы события реального времени обрабатывались вовремя, данные не терялись, буферы не переполнялись, в потоках не возникало разрывов.
R>какими методами она достигается?
Где-то — оптимизацией исходного кода (вынесение тех самых инвариантов, изменение логики и т.п.), где-то — выборочным включением оптимизации для наиболее часто выполняемых участков, где-то — просто отказом от более затратных операций в пользу менее затратных.
Здравствуйте, so5team, Вы писали:
S>ХЗ, я без понятия что такое "типичный современный прикладной проект". А вы, уверен, понимаете в этом еще меньше.
А я ХЗ, как можно понимать "еще меньше", чем "без понятия"
S>Из последнего:
S>- есть конкретное железо на котором крутится софт X и обеспечивает Y rps, нужно на этом же железе обеспечить, минимум, 2xY rps; S>- есть конкретное железо, есть софт от вендора B, некий датасет этот софт на этом железе обрабатывает на ~N секунд. Нужно обеспечить такую же производительность на этом же железе на этом же датасете.
Это что-то очень редкое и нишевое. Глядя на массовый софт, я уже много лет почти не вижу примеров, которые имели бы объем, адекватный функциональности, и работали бы реально быстро на среднем железе, которое тянет такую функциональность. Обычно оно минимум в разы толще/тормознее.
S>Удивительно, и как же на Ada разрабатывают mission critical софт, да еще и в embedded-е...
Точно "на Ada", или таки на "специальных реализациях Ada"? Которые еще и нелегко перенести на другие платформы?
S>Может быть потому, что Ada допускает расширения для конкретных реализаций:
А языки, документация по которым этого не допускает, по-другому реализовать нельзя? Так-то и в реализациях BASIC/Pascal под всякими CP/M и подобными системами, вполне себе есть операции с портами ввода/вывода и произвольными адресами памяти, но сами те системы почему-то не стремились писать на этих языках.
S>Просто потому, что Ada создавалась как универсальный язык для разработки софта для военных. И долгое время был единственным языком, разрешенным для использования в аэро- и космической отрасли.
Может быть, потому, что главной целью ставилась высокая надежность, а не эффективность?
S>Так блин, там же Java (Java, Карл!) в 16KiB ворочалась. Да, это не та Java, которая JavaSE, но все-таки и не Си.
Во-первых, я уже говорил, что 16 кб — это достаточно много. Для тех, кто еще помнит, какого размера был различный софт хотя бы в 70-80-х, и что у некоторых машин все адресное пространство было 32-64 кб. Во-вторых, что там было реализовано из той Java? Можно было запустить там любую программу на Java? Если нет, то нужно оценивать не по самому факту, а по функциональности реализованного подмножества.
ЕМ>>Я говорю про единицы килобайт — это 1-2-4.
S>А вы в курсе, что в этом случае вы имеете дело с нестандартным C++
Разумеется. Но дело-то в том, что сами языки C/C++ построены так, что компактные реализации отсекают лишь специфические элементы, вроде обработки исключений, операций с файлами, процессами и подобным, почти никогда не затрагивая базовых элементов языка.
S>Что вы не имели дела с C++ными проектами хотя бы от 500KLOC и хотя бы от 10 человек.
С человеками понятно — я не люблю работать сообща, а что принципиально изменится, если я таки наваяю проект в полмиллиона строк?
S>вы не осознаете зачем и где нужны все те ругаемые вами фичи C++.
Какие именно? Я последовательно и регулярно ругаю только те фичи C++ (или отсутствие оных), которые создают неудобства в работе с проектами любого объема, и которые оправдываются лишь тем, что она достаточно больших проектах они начинают приносить больше пользы, чем вреда. До сих пор никто не показал, что это был единственный возможный путь развития языка, и нужные фичи нельзя было реализовать так, чтоб они не создавали проблем без нужды.
Здравствуйте, Евгений Музыченко, Вы писали:
S>>ХЗ, я без понятия что такое "типичный современный прикладной проект". А вы, уверен, понимаете в этом еще меньше.
ЕМ>А я ХЗ, как можно понимать "еще меньше", чем "без понятия"
Ну т.е. вообще. Совершенно. Меньше, чем абсолютный ноль.
ЕМ>Это что-то очень редкое и нишевое.
А софт на C++ сейчас -- это что-то очень редкое и нишевое по сравнению с тем, сколько всего пишется на Java, С#, Go, Python, JavaScript.
ЕМ>Глядя на массовый софт
На какой именно?
Например, под Windows у меня из нативного в основном используются: Chrome, Telegram, MS Word и Excel, Lightroom (правда, старый, 5-й версии еще), foobar2000. Ничего из этого не тормозит. Тормоза Chrome, как я понимаю, JavaScript-ом определяются.
Иногда приходится запускать VisualStudio, та да, тормоз еще тот, но ведь она на C#.
S>>Удивительно, и как же на Ada разрабатывают mission critical софт, да еще и в embedded-е...
ЕМ>Точно "на Ada", или таки на "специальных реализациях Ada"?
На Ada под конкретную платформу.
ЕМ>Которые еще и нелегко перенести на другие платформы?
А вы много специфичного для конкретной платформы C++ного кода на совершенно другие платформы переносили?
Это я к тому, что если вы некие требования к Ada предъявляете, то подходите с той же линейкой и к C++.
S>>Может быть потому, что Ada допускает расширения для конкретных реализаций:
ЕМ>А языки, документация по которым этого не допускает, по-другому реализовать нельзя?
Мы все еще про стандарт?
ЕМ>Так-то и в реализациях BASIC/Pascal под всякими CP/M и подобными системами, вполне себе есть операции с портами ввода/вывода и произвольными адресами памяти, но сами те системы почему-то не стремились писать на этих языках.
Может мозги включите (если найдете) и подумаете, почему при наличии такого замечательного чистого Си ту же CP/M пришлось для дохлых персоналок того времени писать на Asm. Upd: Оказывается, там не только Asm, там еще и какой-то PL/M. Но Си нет.
S>>Просто потому, что Ada создавалась как универсальный язык для разработки софта для военных. И долгое время был единственным языком, разрешенным для использования в аэро- и космической отрасли.
ЕМ>Может быть, потому, что главной целью ставилась высокая надежность, а не эффективность?
Да-да-да, так и было. Людям нужно было hard-real time для космических ракет делать, а они на эффективность даже не обращали внимания.
S>>Так блин, там же Java (Java, Карл!) в 16KiB ворочалась. Да, это не та Java, которая JavaSE, но все-таки и не Си.
ЕМ>Во-вторых, что там было реализовано из той Java? Можно было запустить там любую программу на Java? Если нет, то нужно оценивать не по самому факту, а по функциональности реализованного подмножества.
Дяденька, вы дурку включаете специально когда на RSDN пишете? Если не слышали про Java Micro Edition, то погулили бы сперва.
Хотя, если вы всерьез думаете, что на Ada нет указателей на функции, даже при наличии свободного доступа к Гуглу и другим поисковикам, то что уж от вас ожидать, кроме очередной тупизины.
S>>А вы в курсе, что в этом случае вы имеете дело с нестандартным C++
ЕМ>Разумеется. Но дело-то в том, что сами языки C/C++ построены так, что компактные реализации отсекают лишь специфические элементы, вроде обработки исключений, операций с файлами, процессами и подобным, почти никогда не затрагивая базовых элементов языка.
Еще раз для альтернативно одаренных: когда вы от C++ что-то отсекаете (вроде обработки исключений), вы оказываетесь вне текущего стандарта. И зависите от того, что дает вам некая реализация. Это вас устраивает.
А вот когда на конкретной платформе конкретная реализация Ada предоставляет вам типы данных, заточенные под платформу, но не описанные в стандарте Ada, то вы заявляется о том, что это все нестандарт и как же после этого портировать Ada код на другие платформы.
Браво.
А скажите, пожалуйста, поборник C++ного стандарта, а где в стандарте C++ декларируется размерность char, short, int и long? В каком таком разделе указано, что эти типы соответствуют вашей "родной привязки к машинным типам данных (байт, часть слова, составное слово и т.п.)"?
S>>Что вы не имели дела с C++ными проектами хотя бы от 500KLOC и хотя бы от 10 человек.
ЕМ>С человеками понятно — я не люблю работать сообща, а что принципиально изменится, если я таки наваяю проект в полмиллиона строк?
У вас появится проблема большого объема кода. Как минимум. Впрочем, попробуйте, может что-то узнаете.
S>>вы не осознаете зачем и где нужны все те ругаемые вами фичи C++.
ЕМ>Какие именно? Я последовательно и регулярно ругаю только те фичи C++ (или отсутствие оных), которые создают неудобства в работе с проектами любого объема, и которые оправдываются лишь тем, что она достаточно больших проектах они начинают приносить больше пользы, чем вреда.
Вот вам совсем свежий пример из моей обыденной реальности.
Есть некий чисто C++ный проект. В этом проекте используется некая довольно серьезная библиотека логирования.
В одном месте было написано что-то вроде:
Библиотека логирования написана без использования продвинутых C++ных возможностей. Переменное количество аргументов в ней поддерживается через C-шные va_args.
В показанном коде обнаружилась проблема -- когда задается `%s`, то параметр ожидается как wide-string, тогда как x.what() возвращает narrow-string.
Компилятор это пропустил. Неприятно, но не страшно.
Меняем на:
И это мне еще повезло обратить внимание на кракозябры в логе. А сколько еще по проекту таких граблей раскидано?
Все это на фоне того, что предоставляют spdlog и fmtlib на современном C++ с проверками форматной строки и параметров еще в compile-time.
Так что для вас сложные шаблоны и пихание этих самых шаблонов во все дыры может быть и выглядит чрезмерным усложнением, а в проектах, где работают совместно разные люди, эти все возможности (будучи использованы правильно), защищают от кучи ошибок разной степени тяжести.
ЕМ>До сих пор никто не показал, что это был единственный возможный путь развития языка, и нужные фичи нельзя было реализовать так, чтоб они не создавали проблем без нужды.
C++ -- это результат естественной эволюции. Он получился таким, каким получился. Так уж вышло.
Если вы требуете каких-то доказательств что это была "правильная" эволюция, "единственно возможная" и все такое прочее, то вы просто в очередной раз демонстрируете свою альтернативную одаренность.
Здравствуйте, Worminator X, Вы писали:
WX>Несколько раз пытался освоить C++, и всегда забрасывал это дело — сложный, совершенно непонятный язык.
Помимо всего, что тут уже коллеги наговорили про дизайн программы на ссылках и указателях, хочу сказать одну вещь, которая лично мне намозолила глаза ещё со времён паскаля.
Которая растёт из лиспа.
(И которая внезапно проросла в дизайн языка Си и из бага превратилась в фичу)
Почему-то в уйме учебников и учебных курсов происходит подмена понятий.
Список — это сущность, состоящая из других сущностей — элементов.
Но в учебных целях зачем-то говорят, что список — это элемент, который ссылается на следующий элемент и так далее.
В функциональных языках это плотно завязано на иммутабельность данных и на алгебраические типы, но мы же работаем с процедурно-объектно-ориентированным языком!
В си это смешение — не со списками, а с массивами. (Указатель на) массив — это указатель на его первый элемент. И наоборот: указатель на одиночный объект — это массив из одного элемента.
Почему так делается хоть в лиспе, хоть в хаскелле, хоть в си. Тупо из соображений экономии.
Не надо заводить новый тип-контейнер, если можно работать напрямую с его потрохами.
Но в С++ стараются от этого отходить.
std::list<T> — это монолитный объект, владеющий набором объектов std::__blablabla__::__ListNode<T>, которые между собой соединены указателями друг на друга.
И пользователя не пускают напрямую к узлам списка, а только к данным, которые хранятся в этих узлах.
И вопросами создания-удаления узлов занимается объект список, а не каждый узел сам по себе, потому что иначе можно получить всякие проблемы с висячими указателями на пользовательской стороне.
(Их и так можно получить, но прямое управление графом объектов эти проблемы умножит гораздо быстрее).
Здравствуйте, so5team, Вы писали:
ЕМ>>Я говорю про единицы килобайт — это 1-2-4. Обычно для таких МК пишут на голом C, но вся хохма в том, что аналогичный код на C++ порой совпадает до байта, если компилятор один и тот же (например, gcc).
S>А вы в курсе, что в этом случае вы имеете дело с нестандартным C++,
В смысле?
S>т.к. пока что нет для C++ такой штуки, как free standing?
Здравствуйте, T4r4sB, Вы писали:
TB>А что принципиально не так с эффективностью Ады?
Я знаком с Ada лишь очень поверхностно, но создалось впечатление, что язык заметно делает акцент на том, что нужно сделать, а не как это делать, и способов объяснить компилятору подробности там особо не предусмотрено. Соответственно, эффективность зависит от того, сумеет ли компилятор подобрать удачную последовательность машинных команд, или есть ли в конкретной реализации дополнительные способы управления кодогенерацией.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Я знаком с Ada лишь очень поверхностно, но создалось впечатление, что язык заметно делает акцент на том, что нужно сделать, а не как это делать, и способов объяснить компилятору подробности там особо не предусмотрено.
Разве? Там нет принципиальной разницы с С++ в тех вещах, о которых ты говоришь.
Вот жабаскрипт гораздо хуже — там коллекция непонятных сущностей и хрен ты докажешь компилятору что все они — инты. Вернее, лишь при определённых правилах, которые выродились в отдельный диалект
А ещё есть хаскели всякие, где как раз вот о том "что а не как".
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Здравствуйте, пффф, Вы писали:
ЕМ>>>Я говорю про единицы килобайт — это 1-2-4. Обычно для таких МК пишут на голом C, но вся хохма в том, что аналогичный код на C++ порой совпадает до байта, если компилятор один и тот же (например, gcc).
S>>А вы в курсе, что в этом случае вы имеете дело с нестандартным C++,
П>В смысле?
В смысле что если вы компилируете код с ключиком -fno-exceptions в GCC, то вы начинаете работать с диалектом C++, который на данный момент (емнип) не описан стандартом C++.
S>>т.к. пока что нет для C++ такой штуки, как free standing?
П>Чего нет?
https://en.cppreference.com/w/cpp/freestanding
ЕМНИП, работы по формальному определению подмножества C++, которое может использоваться в специфических условиях (например, bare metal), начались недавно и первые результаты ожидаются в C++26.
При этом код на C++ для того же bare metal пишут давно и успешно, но это как с многопоточностью в 1990-х: многопоточные программы на C++ были, а формального определения в C++ стандарте не было и все отдавалось на откуп вендорам компиляторов.
WX>>Для меня пока код на STL и Boost выглядит как магия. ЕМ>Так это магия и есть, причем весьма корявая. Кто-то считает, что это и есть "истинный C++", кто-то так не считает.
Магией это было до C++11.
Даже в этом чати можно найти примеры заклинаний.
Сейчас вопрос "как в компайл-тайм определить наличие метода" даже на SO особо не всплывает. Все стало весьма programmer-friendly.
Другое дело, что многие фичи вроде enable_if для эффективного использования все равно требуют понимания, как templates устроены и что там компилятор себе думает, когда видит твой код.
Здравствуйте, landerhigh, Вы писали:
L>Магией это было до C++11.
Основное, что сделали в C++11 — магию попросту замели под ковер (включили в состав std). В std она по-прежнему реализована на языке C++ — то есть, на его шаблонах. Это даже хуже, чем при обработке операции i++ подставлять из файлика текст сишной функции, возвращающей i+1. Стыдобища. Основные тормоза при компиляции проектов, активно использующих эту магию, возникают на обработке тонн ее шаблонов.
L>Сейчас вопрос "как в компайл-тайм определить наличие метода" даже на SO особо не всплывает. Все стало весьма programmer-friendly.
Там от friendly только то, что теперь, вместо поиска стандартных реализаций магических шаблонов или подключения библиотек, можно включить std. Но сути-то это не меняет — вместо непосредственной выдачи информации из базы компилятора происходит та же самая магия с последовательным перебором шаблонов, пока на каком-то их них не случится облом, что позволяет косвенно получить от компилятора информацию, которую он мог бы выдать и сам.
Суть процесса хорошо описана здесь.
L>многие фичи вроде enable_if для эффективного использования все равно требуют понимания, как templates устроены и что там компилятор себе думает, когда видит твой код.
Именно в этом и заключается убожество реализации. Если язык претендует на поддержку метапрограммирования, в нем должны быть встроенные конструкции для его реализации.
Слава богу, хоть MS додумались реализовать в VC++ встроенные предикаты __is_class, __is_convertible_to и подобные, хотя и их недостаточно для комфортной работы. А по уму, как только стало ясно, что метапрограммирование на C++ набирает обороты, подобные языковые средства должны были внедряться активно и обильно.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Основное, что сделали в C++11 — магию попросту замели под ковер (включили в состав std).
Как будто в этом есть что-то плохое.
ЕМ>Стыдобища. Основные тормоза при компиляции проектов, активно использующих эту магию, возникают на обработке тонн ее шаблонов.
Сегодня основные тормоза при компиляции проектов отрастают от рукожопства при огранизации зависимостей. Шаблоны тут видны только в микроскоп.
L>>Сейчас вопрос "как в компайл-тайм определить наличие метода" даже на SO особо не всплывает. Все стало весьма programmer-friendly.
ЕМ>Там от friendly только то, что теперь, вместо поиска стандартных реализаций магических шаблонов или подключения библиотек, можно включить std. Но сути-то это не меняет — вместо непосредственной выдачи информации из базы компилятора происходит та же самая магия с последовательным перебором шаблонов, пока на каком-то их них не случится облом, что позволяет косвенно получить от компилятора информацию, которую он мог бы выдать и сам.
Но ведь friendly же?
ЕМ>Именно в этом и заключается убожество реализации. Если язык претендует на поддержку метапрограммирования, в нем должны быть встроенные конструкции для его реализации.
Так они и есть. Встроенные.
То, что изначально они не для этого задумывались и не планировались для этого — ну что ж. Когда мобильная связь зарождалась, SMS вообще была шуткой инженеров, к слову.
ЕМ>Слава богу, хоть MS додумались реализовать в VC++ встроенные предикаты __is_class, __is_convertible_to и подобные,
Здравствуйте, landerhigh, Вы писали:
ЕМ>>магию попросту замели под ковер (включили в состав std).
L>Как будто в этом есть что-то плохое.
Убогое — точно есть.
ЕМ>>Стыдобища. Основные тормоза при компиляции проектов, активно использующих эту магию, возникают на обработке тонн ее шаблонов.
L>Но ведь friendly же?
Примерно настолько же, насколько более-менее упорядоченный набор запутанных корявых макросов более "friendly", чем такой же, но бессистемный.
L>Так они и есть. Встроенные.
Они такие же "встроенные", как большинство функций стандартной библиотеки, написанных на C/C++. "Встроенными" обычно называют средства, которые либо вообще невозможно написать на самом языке, либо можно написать только грубо и неэффективно. От того, что тексты шаблонов находятся в файлах, поставляемых с компилятором, а не в файлах отдельной библиотеки вроде boost, они не становятся "встроенными в язык".
L>То, что изначально они не для этого задумывались и не планировались для этого — ну что ж.
Да, тридцать лет назад это можно было считать нормальным. И даже, наверное, двадцать. А сейчас это убожество и позорище.
L>MS всегда были большими затейниками
В данном случае они повели себя более разумно, чем активисты комитета по стандартизации C++.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>В данном случае они повели себя более разумно, чем активисты комитета по стандартизации C++.
Задним числом-то все умны.
А вот сделать язык (платформу), которые дают всю мощь современных плюсов, да встроенными средствами, да чтобы чтобы так, как нравится, а не "как исторически вышло", и при этом с нуля и сразу — слабо?
Здравствуйте, landerhigh, Вы писали:
L>А вот сделать язык (платформу), которые дают всю мощь современных плюсов, да встроенными средствами, да чтобы чтобы так, как нравится, а не "как исторически вышло", и при этом с нуля и сразу — слабо?
Да элементарно вообще. Я еще в середине 90-х, как только начал пробовать C++, сразу же стал задаваться вопросами: как определить объект того же типа, что и параметр функции, член класса и т.п.? как получить у компилятора спецификацию типа в текстовом виде? как сделать условную компиляцию в зависимости от наличия/отсутствия члена класса, свойства типа в параметре шаблона? Спрашивал у коллег, смотрел в интернете — все советовали чрезжопные методы разной степени укуренности, включая нарождавшуюся тогда шаблонную магию.
Если б мне нужно было сделать собственный компилятор под свои нужды, я б быстренько наделал в нем нужных встроенных средств, и наплевал бы на стандарты и совместимость. Но тогда была уверенность в том, что разработчики компиляторов — вроде бы неглупые люди, должны понимать такие простые вещи, коли многие ими интересуются. Любители шаблонной магии тогда воспринимались, как этакие забавные извращенцы, вроде исследователей наркотического транса. Думаю, тогда никому не могло прийти в голову, что эта дурь пойдет в массы, и что этот цирк всерьез и надолго.
Собственно, глядя на политическую ситуацию в мире, уже не так удивляешься какому-то там языку программирования...