Источники недетерминизма

Моя предположительно детерминированная программа производит один из нескольких немного разных выходов на разных тиражах. Вход, компилятор и компьютер неизменны. Я не уверен, какой вывод прав, потому что он всегда выглядит разумным.

Помимо бранного вызова rand(), как это возможно?

Ответ 1

несколькими способами:

  • используя несколько потоков таким образом, чтобы вовлекать расписание данных,
  • используя текущее системное время для ввода,
  • используя неинициализированные переменные,
  • ...

Мы можем сделать больше догадок, но если вы хотите получить значимую помощь, возможно, вам будет полезно опубликовать соответствующие части вашего кода: -)

Ответ 2

Это может быть:

  • Время передачи
  • Любой вход (пользователь, файл, сеть и т.д.)

Ответ 3

Если ваш результат зависит от адреса, выделенного в куче:

int main(int argc, char* argv[])
{
   printf("%p", malloc(42));
   return 0;
}

Для каждого запуска malloc() может возвращать другой виртуальный адрес - не говоря уже о NULL в случае неудачи распределения.

Ответ 4

Помимо блуждающего вызова rand()

rand() полностью детерминирован, пока вы кормите его тем же начальным семенем.

Ответ 5

Не видя кода (СОВЕТ), лучшее, что я могу придумать, будет искать шаблон. Возможно, что-то конкретное дата-время.

Кроме того, попробуйте искать условия гонки. Это может выглядеть недетерминированным.

Ответ 6

Если ваша программа использует float/double, может быть разница в результате, если в какой-либо архитектуре есть контекстный переключатель.

На x86 FPU использует расширенную точность для промежуточного результата, но при сохранении в памяти (что происходит при переключении контекста как процесса или потока) такая точность теряется. Это может привести к небольшому расхождению результата (мы обнаружили такую ​​проблему в нашей программе). Один из способов избежать этой проблемы - попросить компилятор не использовать FPU, кроме SSE для операций с плавающей запятой.

http://www.network-theory.co.uk/docs/gccintro/gccintro_70.html

Ответ 7

Использование значения указателя вместо того, что указывает на всегда, дает интересные результаты.

Ответ 8

В программах, которые мало взаимодействуют с "внешним миром", популярным источником недетерминизма является зависимость от сравнения указателей. Время от времени вы можете увидеть это в коде: когда в функции лексикографического сравнения исходит из вещей, чтобы сравнить (все равно), он сравнивает адреса объектов в качестве последнего средства. Это может привести к различным упорядочениям, если объекты выделены в динамической памяти, поскольку фактические местоположения размещения могут отличаться от платформы к платформе и от запуска до запуска.

Ответ 9

Очевидно, новый экземпляр ошибки Phase of the Moon.

Ответ 10

  • Входы из сети/Интернета.
  • дата/время

Ответ 11

Ты не дал много информации. Тем не менее, как человек, который в реальном времени программирует для жизни наиболее вероятные виновники, которые я ищу, когда такие вещи происходят, это:

  • Использование неинициализированной памяти.
  • Состояние гонки.
  • Некоторая неясная комбинация из вышеперечисленного.

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

Ответ 12

Любое поведение undefined. то есть на сотни страниц будут объясняться все возможные источники изменения выходных данных. Попробуйте выполнить отладку, чтобы найти, где происходит изменение, или прочитать некоторые спецификации С++.