Pull to refresh

Comments 45

У меня товарищ в пакете StarCD считал как-то довольно важную клыльчатку… Потом переставил систему (кажется с 2000 на XP) и продолжил. Результаты получились другие. Прогнал тестовые — совпадают. Прошерстил настройки, почитал доки — так и не понял где засада.
Крыльчатка в ушла в производство в тираж, но «с тех пор в себе я сомневаюсь».
Я сейчас переживаю за новый российский самолет МС-21. Мало ли в каком софте его проектировали по программам импортозамещения.
Тут выход простой — не летайте на нем. Пускай как SSJ поставляют его а страны 3 мира.
К счастью авиация как отрасль софту априори не доверяет, проверяя всё в обязательном порядке экспериментами — продувают в трубах, ломают на стендах… Программа сертификации потом — в натуре надо подтверждать полётами все-все возможные случаи (SSJ напр в Кефлавике пострадал — сертификационный полёт — взлёт на одном двигателе при сильном боковом ветре (что-то там пошло не так — не суть, суть что реально физически летают все тесты и потом дефектоскопируют подробнейше)). Вот с импортозамещёнными хим.компонентами нового композитного крыла — у неспециалистов есть опасения, но это тема целого отдельного холивара.
имею некое отношение к мс-21, могу сказать, что на одном из подразделений используются для проектирования 3д — NX (ранее «Unigraphics»), 2д — nanocad. генерация кода — SCADE.
возможно используются и другие генераторы. Но по своей специфике работы скажу(тестирование авиационного ПО), что каждый используемый код генератор квалифицирован по do-178b/c.
к данному коду не применяются такие активности «код ревью», соответствие код стандарту. но тестирование кода проходит полное и только на основе требований с сбором структурного покрытия кода по уровням DO-178C Level A/B/C для определения неописанного или ошибочного кода.
Сейчас просматриваю огромную базу CWE с примерами. Иногда такая чушь попадается, а ведь кто-то под это дело сертификаты выдаёт. Отсюда у меня такое недоверие ко всякого рода стандартам с длинными аббревиатурами. Профессиональная деятельность оставляет отпечаток на мировоззрении.
Что такое «квалифицирован»? Кем «квалифицирован»? В DO178 нет ничего про средства разработки насколько я знаю. Есть требования к процессу.
Осмелюсь предположить, что засада была связана с использованием каких-то системных функций, выполняющих перевод числа в экспоненциальной форме из символьной строки в собственно числовой тип и/или наоборот.
Довелось тут запускать древний Electronics Workbench 5.12 под Windows 10. Результат моделирования выдавался абсолютно неадекватный. Собираю цепь — источник переменного напряжения, и простейший выпрямитель — диод плюс резистор. Напряжение на резисторе выходит переменное. Мда… Когда второй раз полез в опции анализа, оказалось, что все значения вида 1E-13 стали нулями. Где уж тут нормально считать! В принципе, оно было решаемо записью вида 0.0000001 в поле (на сколько нулей ширины поля хватало). Но была же ещё и куча таких записей в моделях элементов. Всё не переделать. В общем проблема решилась запуском в режиме совместимости то ли с семёркой, то ли с XP.

Проверка мат-пакетов статическим анализатором — это, конечно, хорошо. Но вы проверяете только C/C++ ядро. А сколько там кода, написанного на языке самого пакета (Scilab, MATLAB и т. п.)? Этот код вы проверить своим анализатором не сможете, потому что он динамический и интерпретируемый. И знаете, этот код ужасно написан, хотя бы с точки зрения качества кода и сколько там математических и логических ошибок можно только гадать.


Недавно ковырялся в официальном матлабовском коде


Заголовок

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

Простите, я не очень понял. Какие претензии к тому, что подчеркнуто красным? Кроме жутких имён переменных, которые за матлабом тянутся с 80-х?

Дублирование кода. Вычисление матрицы QtWQ и вычисление выражение для u можно вынести из под условия if else. Условие тут нужно только для вычисления параметра p.


Там весь код так написан, очень сложно читать.

QtWQ в обеих ветках вычисляется одинаково. Поэтому лучше его вынести в безусловное вычисление за пределы развилки.
После того, как это сделано, оказывается, что оба вычисления для u имеют одинаковую форму:

u=((6*(1-p)*QtWQ+p*R)\diff(divdif)


и «else» вообще не нужна, а «then» просто меняет значение p; вычисление u может быть сделано общим кодом после завершения развилки.

Мне лично кажется, что после этих изменений код будет понятнее и сопровождабельнее.

Я, конечно, не могу залезть в голову разработчикам, но попробую предположить, почему сделано так как сделано.
Итак, как я подозреваю, речь об аппроксимации (сплайны?), а Qtw имеет специальный тип, описывающий разреженные матрицы (вызов spdiags). Причём, размерность n на n, где n, веорятно, это число точек кривой.
Если мы идём по ветке if, то приозведение Qtw*Qtw используется дважды — при вычислении p и при вычислении u. В этом случае разумнее избежать повторного очень дорогостоящего вычисления произведения и заранее его сохранить в QtWQ. Если же мы идём по ветке then, то нет необходимости повторного использования произведения, и мы экономим на создании в памяти ненужного (но большого!) QtWQ.
Таким образом, незначительно теряя в читаемости, мы выигрываем в производительности и без того ресурсоёмкой задачи.

> выигрываем в производительности и без того ресурсоёмкой задачи.

Выигрыша нет, QtWQ безусловно и одинаково вычисляется в обеих ветках. Если написано Qtw*Qtw.', это оно же.
Или Вы предполагаете, что в else реально происходят «ленивые вычисления» и работа с QtWQ «размазывается» на остальном? Такое я про матлаб пока не слышал, хотя готов поверить, если подтвердят.

QtWQ нужно вычислять в любом случае, дублируя код мы ни в чём не выигрываем.


Заметьте ещё "однострочники" через точку с запятой. Ради чего тут экономия строк? Это трудно читаемо и усложняется отладка с помощью отладчика.

Я не говорил, что не производятся вычисления. Я говорил, что экономится время на создание новой переменной. Одно дело посчитать значения в ходе вычислений, другое дело создать новую переменную специального типа весьма большой размерности. Тем более, этот код, если я не ошибаюсь, многократно вызывается из цикла.
Я сделал небольшой бенчмарк по построению сплайнов для 10 тысяч точек. Разница совсем небольшая, порядка 0.1 мс на вызов, но предложенная netch80 версия достоверно оказывается медленнее. В доументации пишут, что первая версия этой функции была сделана в 1987. Я не знаю, когда именно был добавлен обсуждаемый участок кода, но у меня есть существенная уверенность, что на тот момент выигрыш в производительности был куда как более заметен.


Да, Matlab известен своим печальным оформлением кода (хотя, если Вы откроете другой код 80ых, то там, возможно, будет что-то похожее. Надо Fortran посмотреть). Но не нужно "негативный ореол" оформления автоматически переносить и на быстродействие/оптимизированность кода. Хотя да, проблемы, как и у всех крупных проектов, бывают.

Этот код в цикле не вызывается, матрицы там разреженные, поэтому то, о чём вы говорите — это какая-то уж совсем микрооптимизация получается. 0.1 мс против читаемости и поддерживаемости кода — это уже слишком, учитывая, что в матлабе вообще всё передаётся по значению (кроме handle based классов). Хотя о чём это я, ООП в матлабе в десятки раз медленее чем обычные функции. :)


В доументации пишут, что первая версия этой функции была сделана в 1987

Изначально этот код был написан на фортране Карлом де Буром для книги. Думаю, что первые версии матлабовского кода написаны им же.


Но не нужно "негативный ореол" оформления автоматически переносить и на быстродействие/оптимизированность кода

На матлабе тоже можно писать нормально, просто это никто не делает, потому что большинство пишут на матлабе write-only "наколенчатый код" лишь бы проверить работу модели или алгоритма.

Вот смотрите. Я пишу
первая версия этой функции была сделана в 1987
есть существенная уверенность, что на тот момент выигрыш в производительности был куда как более заметен.
а Вы мне отвечаете
0.1 мс против читаемости и поддерживаемости кода — это уже слишком

В целом, я не могу понять Ваше тезис. Вы хотите сказать, что разработчики в 1987 году написали более сложный и хуже читаемый код без всяких оснований? Или что спустя 20-30 лет они должны были переписать существующий и работающий код, так как на новом железе выигрыш по времени стал слишком маленьким?

Последний раз этот код правился в 2010 (судя по документации). Я считаю, что код нужно писать так, чтобы он был понятен и легко поддерживаемым. Периодически надо делать рефакторинг. Это не тот случай когда надо упарываться по поводу создавать или не создавать переменную. Мы не живём в 1987 и на фортране уже почти никто не пишет (на самом деле пишут, но не в этом суть). Просто сидят вот такие математики и колбасят вот такой код. Я работал в двух компаниях где практиковалось такое программирование алгоритмов. И каждый раз подобный код просто выкидывался не использовался и писался заново, чтобы потом написать на его основе понятный C++-код для использования в production.


Объясняю свою мысль в контексте этой статьи: подобный код сложно читать и понимать, а значит в нём легко могут затаиться ошибки, которые трудно заметить. И бывает, что подобные ошибки, закрадывающиеся в формулы, даже тестами не отлавливаются.

Вообще, я понимаю, почему вы "защищаете" этот код. У вас в профиле написано, что вы работаете с Matlab. Для вас этот код выглядит совершенно нормально.


Я не перестаю писать о том, что код на Matlab ужасен в 99% случаев, потому что он написан математиками для "калькулятора", каким они считают компьютер, а не для людей.


Вот мой комментарий на эту тему:
https://habrahabr.ru/post/324052/#comment_10121034

Этот код вы проверить своим анализатором не сможете, потому что он динамический и интерпретируемый.

Вряд ли дело в этом :D Скорее у нас просто нет анализатора для этого языка.
Вряд ли дело в этом :D Скорее у нас просто нет анализатора для этого языка.

Именно так :) Ну и в том числе ловить ошибки статическим анализом в языках с динамической типизацией сложнее. Сделайте хороший статический анализатор для Python, которому не нужны аннотации типов, я вас расцелую куплю его. :)

Неплохо, на уровне pylint. Но с аннотациями типов, конечно, лучше.

Кстати о птичках: будет ли поддержка иных языков? Тот же РНР, например, будь он не ладен.
Когда-нибудь мы точно захватим весь рынок такого ПО ;-)
По поводу кривого алгоритма. У них там тестов нет что ли? Совершенно же тривиально тестируется.
Нет, но звучит знакомо. Возможно давно кто-то из коллег пытался проверить, но не было технической возможности это сделать. Могу добавить в список на проверку.
не могли бы вы добавить в список проверки ОСРВ Arinc 653 совместимую разрабатываемую ИСП РАН. ссылка на git
Надеюсь они не сильно обидятся после этого, ведь сами занимаются статическим анализом :D

Лучше добавляйте сразу сюда. И Вы ( PTM, veprbl ) тоже. Не обращайте внимание, что там накопились Pull Request'ы. Я потихоньку их просматриваю и применяю.
ну вот как раз и проверить насколько хорошо их инструмент работает и используют они его при работе ))
Не далее как неделю назад мозг ломал. В зависимости от порядка загрузки файлов, работы с меню или ещё каких-либо совершенно левых действий, Scilab на одной и той же программе выдаёт четыре результата:
1) нормальная работа
2) ошибка на определённой строке
3) подвисание программы
4) вроде нормальная работа, но конечный график — нули
Грешным делом подумал, что глюки 64-разрядной версии. Поставил 32-разрядную. Глюки те же.
А вон оно чё, Михалыч, оказывается…
Здесь вы, к сожалению, правы. Качество C/C++ кода во многих математических библиотеках очень низкое. Причем практически безотносительно к их платности или бесплатности. Нередко все заканчивается переписыванием функций с нуля, что терпимо для открытого кода, но сильно раздражает в платном софте.

Ну там в репорте видно, что и Коверити находит у них уйму проблем. Так что дело не в анализаторе, а в разработчиках и их ресурсах.

мне только одно не понятно — ошибка в умножении матриц, это как вообще? этой библиотекой вообще не пользуются?
Point Cloud Library, по которому и нашлась библиотека в зависимостях. Вроде делают что-то серьёзное и как-то живут с такими ошибками.
MC-21 многое сделано на matlab/simulink. Военный Сухой делает скв и сард в нашем софте — SimInTech. Рассматривают его использование для остальных систем. Гражданские самолёты Сухого — matlab/simulink. Причём походу это не свой осознанный выбор, а так как ЦАГИ для них что-то делает. Ил размышляет. Но некоторые стенды уже с SimInTech. И да, выбранный софт никак не влияет на качество аппарата, там действительно большое количество испытаний, скорее на его стоимость.
Если в тулбоксе нет тестов, которые проверяют умножается ли матрица на число корректно, то им не стоит пользоваться.

По поводу этой ошибки, скорее всего вы нашли какую-то заброшенную часть кода, которая никогда не выполняется. Иначе бы эту багу уже давно заметили, уж слишком тривиально и ведет уж к слишком другому результату. Ну или этим пакетом просто никто не пользуется.
Про https://root.cern.ch интересно было бы почитать. Там своя копия llvm, её можно особо не проверять. Пожалуй, наиболее важные компоненты будут: core, io, tree, hist и math. Я так понимаю у них там уже используется Coverity.
Немного оффтопа: в научной школе М.А. Миллера по поводу ошибок была в ходу такая шутка-спор: Один говорил: «Я возьму любую диссертацию, открою на случайно странице и найду ошибку». Как правило оппонент тушевался и не знал что отвечать. Правильный ответ: «А я найду две!»
Так и живем.
Sign up to leave a comment.