Ivan Ustûžanin, Надо же! Я проглядел, что вы написали smart_ptr<SomeClass>(&object)
ещё вчера! Мне показалось, что написано "make_shared". И именно эта конструкция и оказалась ошибочной!
Ivan Ustûžanin, Разобрался в чём дело.
Это я написал вчера, когда повёлся на маркетинг, что std::shared_ptr - "умные". Думал, что, наверное, разберуться сами. А оказалось, что нет. Приводить к типу "std::shared_ptr" не очень хорошая идея оказалась. )))
Ivan Ustûžanin, Спасибо за подсказки в любом случае, я про такие тонкости с make_shared не знал, но с другой стороны и начал этим заниматься, чтобы и в плюсах разобраться.
>>так Exception или падение?
Там именно подение. У меня там есть перехват std::exception, но на access violation - это как "против лома нет приёма".
Если разберусь с ошибкой - напишу, в чём было дело.
Ivan Ustûžanin,
>>выкиньте этот Contour(), make_shared() и так делает новый объект
Спасибо за подсказку, не знал, что так можно, но наверное так работает только если есть конутруктор по-умолчанию. Выкинул, но не помогло (в том плане, что shared_ptr создаёт объект, но Exception всё равно вылетае на старом месте). Так-то иногда надо вызвать явный конструктор с параметрами.
Ivan Ustûžanin, Это не полный код, который может ввести в заблуждение. Далее frame_outer_boundary добавляется в std::vector, который приходит сильно из другого блока кода. И сыпется точно не на этом объекте:
В стандартных примерах по ссылке, которые вы прислали, не очень понятно почему вызываются деструкторы - толи new выходит из области действия блока кода, то ли shared_ptr-ы. Не ясно кто стартует вызов деструкторов - сами исходные объекты или shared_ptr ?
Ivan Ustûžanin,
И честно говоря мне не очень понятно что такое "объект создан на стеке, то как его в shared_ptr не пихай, его деструкторы будут вызваны при выходе из блока". Вот на скрине объект создан на стеке или нет?
mayton2019 В принципе я так и поступил в итоге - стал нагружать данными в несколько потоков, которая стала близка к количеству ядер и тогда загрузка ядер стала заметно подниматься почти до 100%. У меня сложилось впечатление, что при одном потоке операционка так умело перекидывала эту задачу в однопоточном режиме между ядрами, что диспетчер задач даже при работе в быстром режиме отображения нагрузки не успевал отслеживать настоящую нагрузку на одно ядро. А как только не осталось ядер для перебрасывания, тут-то процессор и завым всеми вентиляторами. )))
Так что видимо проблема была просто в некачественном отображении загрузки на ядро в диспетчере задач! В подтверждении этого предположения говорит факт, что профайлер студии писал 4-5% от общей загрузки всего процессора по этой задаче, что примерно и соответствует полной нагрузке одного ядра в 24 ядерной системе, на которой всё это и работает.
В результате чего каждый вызов сишного кода из питона создает новый поток для выполнения очень простой и короткой операции.
Точно нет. Если данные удаётся разделить на 20 независимых потоков, то исчитаются они в 20 раз быстрее, даже при делении потоков в Python. В данном случае у меня есть Cишная библиотека, которую я подключаю к Python (такая схема работы, нужно затащить сишную программу через обёртку, это точно не узкое место). На чистых тестах в C++ один поток тоже может считаться также долго, как и через python. Разницы нет. Вся логика уже в C++. Питон только подготавливает данные, а там их не много. Массив на 2000 точек по три [[0.5, 1.1, 0.0], ...] и список индексов примерно такого же размера или меньше. Для питона переварить такое в виде того же процесса подготовки данных для передачи в C++ вообще ни о чём.
Wataru, Эта самая параллельность тут роли не играет. Если у меня случается один большой расчёт, то и идёт он в один поток, думаю, что RtlUserThreadStart отображается с учётом того, что он выполняет задачу, а не потому что долго вызывается. Если у меня случается так, что тот же объём данных можно разбить на независмые 20 потоков, то и считаются они в 20 раз быстрее. Ниже написал, что может быть я немного ошибся с оценкой производительности, но в целом меня смущает, что я не вижу загрузки хотя бы по одному ядру на 100% в диспетчере задач. Что работает процесс расчёта, что не работает - нет какого-либо отклонения ни в одном ядре. Однако стоит запустить несколько процессов в параллель, тогда видно, что некоторые ядра нагрузились по 100%, но это если потоков много. Если так в целом судить, то скорее всего может быть я неправильно интерпретирую данные? но в принципе хотелось бы понять, где вообще программа тупит.
Из читаемого в профайлере:
почему 54% на скобке?
Wataru, Мне сейчас пришло осознание, что про 10-15 процентов - это я ошибочно определил, т.к. речь идёт о 2-4% от всех CPU, которых у меня 24 ядра. 2-4% Показывал диспетчер задач:
В профайлере показывает так, но вот Kernel-то меня и смущает? Почему "какой-то" kernel занимает 86%, а программа только 13.5?
Уверен, что 10-15% от ядра, программа не распараллелена, точно однопоточное. Пауз sleep точно нет. Работа с библиотекой GMP/MPFR, но, по моему это не важно, т.к. GMP вполне умеет нагружать как надо. Обращение к памяти вполне может быть очень активным, т.к. много чего делается на std::vector. Но действительно ли это обращение так сильно влияет на производительность? Почему само выделение/освобождение памяти проходит так медленно, с учётом того, что оно сама память по объёму в программе не сильно меняется за время расчёта?
mayton2019, Профиллировщие говорит, что больше всего cpu потребляется вне программы, поэтому я предположил, что может быть тратится время на работу с памятью:
Wataru,
Спасибо за подсказку, не знал такого способа, но ничего подобного не нашёл. Есть ли ещё способ как-то переключить вывод? (Я понял прикол, попробую ещё что-то поискать).
res2001, Пример есть, но от этого не легче:
Полный код, к сожалению, дать не могу.
В режиме Debug выводится и 1 и 2, а в режиме Release, только 1. Причём я сделал тестовое консольное приложение в Visual Studio 2022 и в нём выводится 1 и 2 и в режиме Debug и в режиме Release.
Сейчас перевожу свои сообщения на printf и это меня вполне устраивает, т.к. сообщения клиенту всё равно формируются в exception-ах. Консольные сообщения больше нужны для "визуального" анализа в процессе работы, не хотелось париться в форматированием в printf.
brar, Забыл написать, что на моей памяти есть и противоположный пример. Есть такая компания Аскон, о ней я слышал положительный отзыв. Работал в относительно большой проектной компании тыщи на полторы человек, админом. Там внедряли Компас 3D, около двухсот лицензий, лет 25 назад, и тогда было приятное впечатление, что они даже чуть не ночевали с нашими сотрудниками, пока внедряли. Тогда лезли из кожи вон. Сейчас не знаю. )
Так-то у нас на работе шутят, что альтернативой импортному ПО является, не российский аналог или свободное ПО, а "ломанное" импортное ПО.
И дело не в том, что оно отечественное не такое уж и не годное, но вот сколько проблем было, чтобы как-то заставить Autodesk приоткрыть формат и они немного уступили совместимому формату Teiga, но вот заменить Adobe вообще непонятно чем, не особо то их форматы и читаемы, кажется. Может как-то частично и можно их во что-то импортнуть, но если уж если у вас много библиотек внутренних под них, так очевидно, что тут всё плохо.
Это мы ещё про редактирование полигональной графики не вспомнили. Можно было бы вспомнить про тот же Blender (я, кстати, его немного знаю) и мог бы посоветовать его, что в нём можно писать вполне приличные плагины на Python, которые вполне можно было бы попробовать загнать в качестве альтернативы расчётным программам для внутреннего пользования. Обычно пытаются писать сразу на Python и ищут пакеты визуализации под него, но получается в основном в PyPlot, который только для математических расчётов подходит, а уж про генерацию моделей речи не идёт, а вот с Blender вполне может получится неплохая альтернатива расчётным программам, т.к. это визуализатор, в который встроен Python. Т.е. инверсный подход первому случаю, не Python+визуализатор, а Визуализатор+Python. Но это так, личное мнение, просто как пища для размышления ))), а не как альтернатива чему уже устоявшемуся.
Станислав Романов, Вы ошибаетесь! Я далеко не большой специалист по ЯП, но кое что приходится делать. Свой первый ЯП написал вообще на LISP, хотя на тот момент знал C++. Тот ЯП был примитивный, не было циклов, но нашим дизайнерам в то время зашёл на ура (это был интерпретатор для отрисовки фирменных конструкций в автокаде). Что-то близкое к регуляркам. И это тоже ЯП. Отбросьте сомнение, что ЯП - это только что-то монстрообразное типа C++, C#, JAVA, Python. Это может быть и короткий набор инструкций. Есть у меня программа, которые генерит себе код на основе других выражений и сама же их выполняет (есть у меня такой необычный проект. И проект этот смог сделать только я один, потому что никто не знал как к нему подступиться вообще, потешил самолюбие). Поверьте - синтаксический анализ, на котором строится любой ЯП - дикая ахилесова пята программирования. Никто не хочет его изучать, а он нужен много где.
Корректнее ли код (1) переписать в (2)?
Почему не работает такая конструкция? Ведь её проще и короче написать?