Сила - в правде. На уровне программирования она выражается в том, что одни и те же программы при одних и тех же начальных условиях обязаны выдавать истинную правду, т.е. одинаковые результаты. И даже разные программы, реализующие одну и ту же задачу, должны вести себя одинаково. Действительно, было бы странно, если бы два калькулятора выдавали отличающиеся результаты на одной и той же операции. Или, по-другому, все это своего рода «программистская аксиома».
И, вроде бы все так, да не всегда. Критично ли наличие ошибок в программах? Странный вопрос - конечно, критично. Но, тем не менее, найдутся и те, кто скажет – не беда. И даст этому свое объяснение. Здесь, правда, можно вспомнить, как фирма Intel объясняла несущественность ошибки деления с плавающей точкой в процессоре Pentium (подробнее см. [1]). Но общественность и пользователи объяснили Intel, что она не права. И, понеся большие репутационные и финансовые потери, ей пришлось с этим согласиться и исправить положение.
Далее, обсуждая конкретные программы, мы столкнемся с тем, что нужно считать ошибками. Отличие от ситуации с Intel только в том, что необходимо будет конкретизировать, кто ошибается и ошибается ли и где источник ошибок. Но то, что идет явно не по плану, подтверждают результаты нашего тестирования. Просто ситуация несколько сложнее проблемы одной операции деления FDIV.
Итак. Выберем для экспериментов три среды: две известные – это MATLAB, SimInTech и одну, известную больше по статьям вашего покорного слуги, - среду параллельного автоматного программирования ВКПа. Для первых двух можно скачать ограниченные версии. Их возможностей вполне будет достаточно для наших примеров. Ну, а в отношении третьей - придется довериться автору.
Соберем в рамках упомянутых сред простую схему, состоящую из трех блоков - генератора синусоидального сигнала, интегратора и блока отображения. На рис. 1, 2, 3 представлены как подобные решения, так и результаты их работы. И пока ни что не вызывает беспокойства.
Для пущей уверенности мы собрали еще одну аналогичную схему, заменив только синусоидальный генератор на генератор импульсных сигналов. Но это в целом ситуацию не изменило. Хотя, что там греха таить, основная цель всех этих экспериментов была все же проверить «честность» блока интегрирования среды ВКПа и, если необходимо, доработать его функциональность.
Далее в рамках тестирования ВКПа на примерах все более сложных задач мы создали схемы аттракторов, описанных в статье на Хабре [2]. Это аттракторы Лоренца, Ресслера, Рикитаки и Нозе-Гувера. В статье они представлены схемами в МАТЛАБ. Аналогичные схемы мы собрали для SymInTech и ВКПа. Сравнительные результаты их тестирования оказались столь любопытны, что заслуживают того, чтобы с ними был ознакомлен и Хабр.
При этом отличия в результатах тестирования аттракторов Лоренца проявились в наибольшей степени. Они приведены для МАТЛАБ на рис. 4, для SymInTech - на рис. 5 и для ВКПа на рис. 6. Глядя на результаты можно лишь сказать, что они похожи и не более того. Поэтому, анализируя их, надо бы признать, что они фактически опровергают сформулированную нами ранее «программистскую аксиому». С таким положением мириться нельзя и это, безусловно, требует своего разбирательства и поиска причин случившегося.
Почему сертифицированный SimInTech выдает результаты, которые отличаются от, наверное, столь же сертифицированного пакета MATLAB? Может, можно все списать на хаос, который моделируют аттракторы? Однако, повторный перезапуск программ свидетельствует о его отсутствии.
Но автора обеспокоило совсем другое - достаточно сильное на фоне остальных программ отличие результатов, показанных ВКПа. Отметим также, что перезапуск ВКПа порождал близкие, но все же отличающиеся результаты. Т.е. в какой-то мере они больше отвечали поставленной цели – моделированию хаоса. Но причины этого достаточно понятны. К хаосу они имеют мало отношения и это мы объясним позже.
И тут пришло время вспомнить про параллелизм. Уравнения каждого из аттракторов представляют собой систему из нескольких параллельных дифференциальных уравнений. Но только у ВКПа можно выбрать один из двух режимов работы: использовать при расчетах теневую память (это стандартный режим, обеспечивающий параллельные свойства среды [3]) или работать в обычном режиме. Напомним, что в режиме теневой памяти измененные на текущем такте данные помещаются в буфер, чтобы, когда выполнятся все действия, стать новыми значениями. В обычном режиме данные обновляются ровно в моменты их изменений.
После изменения режима расчета в ВКПа были получили графики, представленные на рис. 7. Сам режим работы при этом определяется состоянием переключателем shadow mode of variables (см. рис. 7), т.е. код вычислительных процессов ни как не затрагивается. Как можно видеть, полученные графики в большей степени походят на результаты конкурентов, чем на свой, но полученный в теневом режиме работы среды. Из этого следует, что два других пакета, решая поставленную задачу, скорее всего, вычисления выполняют строго последовательно, искажая тем самым «правду».
С подобной проблемой параллельных расчетов автору уже приходилось сталкиваться. Тогда участником экспериментов был пакет LabVIEW и решалась проблема моделирования адаптивного ПИД-регулятора (об этом см. статью на Хабре [4]). Значения данных, рассчитанных пакетом, полностью совпадали со значениями, полученными в ВКПа, но были сдвинуты по времени. Это говорило о последовательной работе созданных моделей объекта и регулятора. Доказано это было, как и выше, путем изменения режима работы среды.
Разные же результатов у ВКПа от запуска к запуску объясняются принципом работы ядра среды. Если первые два рассчитывают работу приложения, то ВКПа ее именно моделирует. Это происходит в дискретном времени, длительность такта которого «плавающая». Эту разницу соответственно и «ловит» блок интегрирования. Отсюда и некий «хаос» в поведении аттрактора в ВКПа. Но, еще раз, он вполне объясним и потому даже ожидаем.
Основное вывод, который следует сделать, сводится к тому, что современное программирование, как ни крути, а «антипараллельно». А потому в его рамках сложно в полной мере доверяться даже достаточно известным программным пакетам. Но самое опасное в том, что они используются огромным числом специалистов, не подозревающих о тех последствиях, которые могут произойти, если им доверяться всецело и безоглядно.
В их оправдание можно лишь сказать, что ни MATLAB ни SimInTech лишь отчасти виноваты в том, что не учитывают параллельные свойства реальных систем. Они просто следуют тенденциям и понятиям современного программирования. А те «сертификации», которые они успешно проходят, похоже, столь же "антипараллельны", как и само современное программирование.
По-хорошему теперь нужно ждать разъяснений по поводу разницы в результатах «обычных» прогонов, а также по поводу учета параллелизма, как программных, так и вполне реальных систем. Это особенно важно, т.к. в перечень решаемых пакетами задач входят те, которые весьма критичны к ошибкам. Вдруг, не дай Бог, что-то не так взлетит, не туда попадет, внезапно откажет или не вовремя утонет? Такой хаос нам не нужен!
Приложение
Схемы аттрактора Лоренца в MATLAB, SymInTech, ВКПа
Схемы остальных аттрактор аналогичны и результаты их тестирования достаточно похожи друг на друга. Даже в обоих режимах работы ВКПа.