Получить время выполнения параллельной программы на Прологе

Я использую SWI Prolog, и у меня есть программа, которая выглядит следующим образом:

main :-
   statistics(runtime, [T0|_]),
   thread_create(...),
   thread_create(...),
   thread_join(...),
   thread_join(...),
   statistics(runtime, [T1|_]),
   T is T1 - T0,
   print(T).

Проблема в том, что по какой-то причине T всегда равно 0. Однако, если часть thread_create / thread_join заменить ее эквивалентным серийным кодом, я получаю ненулевое время.

«Обходной путь» (но я думаю, что это не на 100% правильно), который я нашел, использует walltime вместо runtime в качестве первого параметра для statistics/2, но я читал, что время стены похоже на фактическое время, которое я мог бы измерить, скажем, настоящие настенные часы и не должны использоваться для измерения времени выполнения программы.

РЕДАКТИРОВАТЬ: Кроме того, если я добавлю аналогичный механизм синхронизации в цель каждого потока, тайминги также будут ненулевыми. Я предполагаю, что runtime измеряет процессорное время только для потока, в котором он запущен, и оценивает его как 0 в первом потоке (тот, в котором работает main), потому что этот поток делает очень мало, кроме делегирования реальной работы вновь созданным потокам.


person PhantomR    schedule 12.05.2018    source источник
comment
К сожалению, использование system_time так же, как и в исходном посте, не только дает T, равное 0, в main, но и в цели каждого потока (среда выполнения работала, если была помещена в функцию каждого потока).   -  person PhantomR    schedule 13.05.2018
comment
Ну, я думаю, что ваш анализ в конце правильный, поэтому просто измеряйте в каждой нитке.   -  person Tomas By    schedule 13.05.2018
comment
Это немного сложнее сделать (мне придется добавить эти тайминги), но я также подумал, что получение этой статистики для каждого потока увеличит время выполнения потоков. Тем не менее, я заметил, что измерение времени стены на самом деле ОЧЕНЬ точное. Время, которое я измеряю, используя время стены в main, почти такое же, как максимум между временем выполнения каждого из потоков.   -  person PhantomR    schedule 13.05.2018


Ответы (1)


Вы используете ключи совместимости, в основном исходящие из Quintus Prolog, когда не было потоков, а миллисекунды считались очень точными. Используйте родные ключи. Один из них — process_cputime, возвращающий процессорное время всего процесса (всех потоков). Также thread_cputime возвращает время ЦП всех завершенных потоков и только cputime возвращает время вызывающего потока. Все значения являются числами с плавающей запятой, выражающими время в секундах. Разрешение зависит от ОС, обычно достаточно точное для современных ОС.

person Jan Wielemaker    schedule 13.05.2018
comment
Я на самом деле попробовал первые два, но я хотел бы получить время выполнения всей программы (которое, я думаю, должно быть значением, близким к максимуму времени выполнения потоков). Единственный способ получить это, чтобы сделать что-то вроде statistics(cputime,T0),..statistics(cputime, T1), T is T1 -T0 в каждом потоке, вернуть это T и вычислить максимум всех T после объединения всех потоков? - person PhantomR; 14.05.2018
comment
process_cputime делает это. Это включает в себя время обработки завершенных потоков. Все это может зависеть от операционной системы хостинга, поскольку существует довольно много различных способов реализовать это, и все они работают на некотором подмножестве операционных систем. - person Jan Wielemaker; 14.05.2018