Воспроизвести рандомы

Общие вопросы программирования, алгоритмы и т.п.

Модератор: Модераторы

Re: Воспроизвести рандомы

Сообщение скалогрыз » 29.05.2016 05:25:52

я бы не стал сильно волноваться из-за сторонних библиотек. Хотя теоретическая возможность варварского обращения библиотеки с рандомом есть, вроде вызова randomize() или назначения randseed, без восстановления значения; авторы библиотек обычно люди достаточно грамотные, чтобы этого не делать.

я бы посмотрел ещё в сторону как random() используется. А точнее из каких потоков. Radnom() всё-таки основан на глобальных переменных, и порядок вызовов в нём критичен. А если он вызывается из разных потоков, то порядок вызовов возможно будет очень трудно гарантировать.
скалогрыз
долгожитель
 
Сообщения: 1803
Зарегистрирован: 03.09.2008 02:36:48

Re: Воспроизвести рандомы

Сообщение sign » 30.05.2016 07:06:31

Дож писал(а):
Какой смысл в рандоме если его надо повторять ?
Тогда уж создать файл с шумом и подкладывать, кроссплатформенно, надежно

Мне не нужен невоспроизводимый рандом, у меня не криптография.

Вы не поняли идею!!!
Запишите в файл данные генератора случайных чисел. Размер файла определите по своим нуждам. При исчерпании - читать с начала.
Потом используйте этот файл, как источник случайных чисел.
Всякий раз, когда программа будет читать с начала файла, она получит гарантированно повторную последовательность.
sign
энтузиаст
 
Сообщения: 1131
Зарегистрирован: 30.08.2009 09:20:53

Re: Воспроизвести рандомы

Сообщение скалогрыз » 30.05.2016 07:19:52

sign писал(а):Потом используйте этот файл, как источник случайных чисел.

ээээ.... для того чтобы этот метод считать псевдослучайным, размер файла должен быть 16Gb :)
(2^32 чисел по 4 байта на число)
скалогрыз
долгожитель
 
Сообщения: 1803
Зарегистрирован: 03.09.2008 02:36:48

Re: Воспроизвести рандомы

Сообщение sign » 30.05.2016 11:51:42

С чего вы решили, что его программа использует ПСЧ в таких объемах?
Может там вообще не больше миллиона чисел берётся!
sign
энтузиаст
 
Сообщения: 1131
Зарегистрирован: 30.08.2009 09:20:53

Re: Воспроизвести рандомы

Сообщение Дож » 31.05.2016 19:08:31

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

При этом хочется всё это организовать чем-то подключаемым, что можно безболезненно от программы отсоединить, и не останется ушей типа своих рандомов как будет при перефигачивании всех базовых юнитов на свой особый рандом. Буду за RandSeed цепляться до последнего :) (Ещё можно пытаться патчить RTL и пересобирать его вместе с прогой.)

Пока что я вроде получил нужные рекомендации и выбрал вариант — если узнаю что-нибудь новое или неожиданное, отпишусь сюда :)

я бы посмотрел ещё в сторону как random() используется. А точнее из каких потоков. Radnom() всё-таки основан на глобальных переменных, и порядок вызовов в нём критичен. А если он вызывается из разных потоков, то порядок вызовов возможно будет очень трудно гарантировать.

Тут даже безотносительно воспроизведения всё весело: так как random не thread-safe, то при использовании его в других потоках придётся либо критическими секциями его использование обкладывать, либо свои рандомы юзать.
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 899
Зарегистрирован: 12.10.2008 16:14:47

Re: Воспроизвести рандомы

Сообщение скалогрыз » 31.05.2016 19:44:31

sign писал(а):С чего вы решили, что его программа использует ПСЧ в таких объемах?
Может там вообще не больше миллиона чисел берётся!

всегда рассматриваю худший вариант.

Дож писал(а):Тут даже безотносительно воспроизведения всё весело: так как random не thread-safe, то при использовании его в других потоках придётся либо критическими секциями его использование обкладывать, либо свои рандомы юзать.

тут, к сожалению, проблема даже не в критических секциях, а проблема в очереди вызова random().

Например, если рандом вызванный 4-раза даёт такие вот числа:
110 220 330 440

То на целевой машине, потоки могли получить эти цифры следующим образом:
Поток1: 110
Поток2: 220
Поток2: 330
Поток1: 440

(допустим что оба потока работают по следующему алгоритму:
* получить рандом
* прочитать файл
* получить второй рандом)

На твоей машине, порядок вызова random() может оказаться иным:
Поток1: 110
Поток1: 220
Поток2: 330
Поток2: 440
Просто потому что так распорядилась система, и поток 1 успел быстрее прочитать файл.

Т.е. даже если вызов был обёрнут в критическую секцию, и с точки зрения целостности и обращения с данными всё было чисто; то с точки зрение исполнения твоей системы возникает этакий макро-race condition.

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

а зачем рандом? и если логи всё-равно ведутся, то может быть записывать результат рандом-а, а не seed?
скалогрыз
долгожитель
 
Сообщения: 1803
Зарегистрирован: 03.09.2008 02:36:48

Re: Воспроизвести рандомы

Сообщение Дож » 31.05.2016 20:18:48

тут, к сожалению, проблема даже не в критических секциях, а проблема в очереди вызова random()

Да это всё понятно, что потоки вносят недетерминированность в работу программы.

Я к тому, что если есть потоки, и в них используется System.Random, то либо в них уже задействованы критические секции и программист знает какие именно и как ему безопасно вызывать System.Random, либо его программа уже нерабочая.

И в первом случае непонятно зачем ему вызывать System.Random, потому что если делать всё «по науке», то каждому потоку нужно иметь свой инстанс рандома, а в такой ситуации удобныей использовать не System.Random, а какой-то многопоточный. Можно выбрать тот, который воспроизводим, и который можно проинициализировать сидом при старте потока.

а зачем рандом? и если логи всё-равно ведутся, то может быть записывать результат рандом-а, а не seed?

Ну вот есть у меня, например, такая функция
Код: Выделить всё
function Rand2f(L, R, B, T: TFloat): TVec2f;
begin
  Result.X := Random * (R - L) + L;
  Result.Y := Random * (T - B) + B;
end;


Где в программе логгировать? Впендюривать прямо в Rand2f, общую корневую функцию, ничего знать не знающую о рандомах, логгировании и прочем, или везде бегать и вставлять в месте вызова этой Rand2f сохранялку TVec2f, делающую репродукцию реальных результатов Random'ов? Точно ли я везде всё в программе залоггировал, как убедиться? А если есть RandRect2f, то, наверное, логирование нужно будет впендюривать не в общую корневую функцию RandRect2f, а в места её вызова. Не забыл ли я заодно про Rand3f и Rand2i? TList.Shuffle и TArray.Shuffle я учёл? Везде ли я подменил Random на свой, даже в чужих библиотеках? Вот я хочу заюзать библиотеку VasyaPupkin у себя в проекте — надо бы прочекать как там обстоят дела с Random'ами, вдруг она, о боже, их использует? Что будет, если я захочу оторвать всё это безобразие от программы, так как оно мне просто надоело, сколько усилий я затрачу на отрывание? Вдруг Rand2f в программе будет дёргать 10000 раз в секунду, прога не гикнется от такого количества записий в файл? Надо бы замерить «Random Rate», чтобы знать в каких ситуациях можно будет использовать такое логгирование.

Я это к чему. На словах-то это просто звучит «не seed сохранять, а результаты», а на деле поддержка кода усложняется лавинообразно.
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 899
Зарегистрирован: 12.10.2008 16:14:47

Re: Воспроизвести рандомы

Сообщение скалогрыз » 31.05.2016 22:25:43

Дож писал(а):Можно выбрать тот, который воспроизводим, и который можно проинициализировать сидом при старте потока.

Мне кажется тут нужно спросить автора программы:
* Вызываются ли Random() в потоках. Т.е. если нет, то шансы использовать только Randseed увеличиваются
* Вызывают ли сторонние библиотеки Randomize и/или меняют Randseed по своему усмотрению. Если нет, то всё хорошо, если да... то нужно разбиратся.

Но если random всегда однопоточный, и никто не изменяет randseed произвольным образом, то можно с 100% увереностью полагаться лишь только на начальное значение Randseed-а, как на надёжное и кроссплатформенное решение.

Дож писал(а):Где в программе логгировать?... а на деле поддержка кода усложняется лавинообразно.

Ну конечно лавинообразно, если изначально в требованиях к программе не было заложено "тотальной слежки" то внедрение этой "тотальной слежки" будет дорогим удовольствием :)

Либо придётся смотреть в очень низкоуровневые решения, вроде инъекций кода, который подменит Rand() функции на свою реализацию с записью в журнал. Между прочим вариант потенциально более дешёвый, чем тотальное изменение программы, но с требованием Админиских прав при запуске :mrgreen:
скалогрыз
долгожитель
 
Сообщения: 1803
Зарегистрирован: 03.09.2008 02:36:48

Re: Воспроизвести рандомы

Сообщение zub » 30.04.2017 19:04:26

Предлагается похожая фича http://bugs.freepascal.org/view.php?id=31737
zub
долгожитель
 
Сообщения: 2884
Зарегистрирован: 14.11.2005 23:51:26

Re: Воспроизвести рандомы

Сообщение MysticCoder » 01.05.2017 18:03:22

Внесу свои пять копеек... Выше уже говорили про потоки... Еще есть возможность словить недетерминированность по логике программы. На примере игры в крестики нолики: во время игры могут вызываться куча рандомов для эффектов частиц, которые в течение времени меняют рандсид, плюс к этому можно добавить рандомы для эффектов тряски камеры, а это уже не только время меняет рандсид, а еще движения мыши. В таком случае можно и нужно использовать не только потокозависимые рандомы, но еще и целые ветки рандомов. Одна ветка рандомов со своим рандсидом будет работать чисто на эффекты, другая чисто на камеру, третья - на АИ. Возможно, здесь не тот случай, но пусть здесь будет :)

Upd. еще есть вариант сплайсинга функций. В винде(по крайней мере до 7 включительно) можно спокойно перезаписать используемый компилятором рандом(скорее всего разные библиотеки используют разные его реализации, так, что перехватывать придется несколько). В других ОС не знаю как с этим дело обстоит.
MysticCoder
постоялец
 
Сообщения: 154
Зарегистрирован: 14.09.2013 00:20:28

Пред.

Вернуться в Общее

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4

Рейтинг@Mail.ru