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

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

10 голосов
/ 31 августа 2010

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

Кроме случайного вызова rand (), как это возможно?

Ответы [ 12 ]

17 голосов
/ 31 августа 2010

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

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

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

7 голосов
/ 31 августа 2010

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

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

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

7 голосов
/ 31 августа 2010

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

  • Время резьбы
  • Любые данные (пользователь, файл, сеть и т. Д.)
5 голосов
/ 31 августа 2010

Помимо случайного вызова rand ()

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

3 голосов
/ 01 сентября 2010

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

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

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

3 голосов
/ 31 августа 2010

Не видя некоторого кода (подсказка), лучшее, что я могу придумать, - это поиск шаблона. Может быть, что-то конкретное время и дата.

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

2 голосов
/ 31 августа 2010

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

1 голос
/ 31 августа 2010

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

0 голосов

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

0 голосов
/ 31 августа 2010

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

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

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

...