Почему количество байтов, переданных TIME, отличается для разных вызовов?

Используя SBCL 1.4.12, я просматриваю упражнение 17.9 из книги Стюарта Шапиро Common Lisp: An Interactive Approach и определяю время применения функции reverse к списку из 10 000 элементов. Когда я определяю время этой функции, используя один и тот же список, функция time каждый раз сообщает о различном количестве байтов.

Вот код функции reverse:

(defun reverse2 (l1 l2)
  "Returns a list consisting of the members of L1 in reverse order
   followed by the members of L2 in original order."
  (check-type l1 list)
  (check-type l2 list)
  (if (endp l1) l2
      (reverse2 (rest l1)
                (cons (first l1) l2))))

(defun reverse1 (l)
  "Returns a copy of the list L1
   with the order of members reversed."
  (check-type l list)
  (reverse2 l '()))

Я сгенерировал список в REPL с помощью:

(defvar *test-list* '())
(dotimes (x 10000)
  (setf *test-list* (cons x *test-list*)))

Вот результаты четырех тестовых прогонов:

CL-USER> (time (ch17:reverse1 *test-list*))
Evaluation took:
  0.000 seconds of real time
  0.000000 seconds of total run time (0.000000 user, 0.000000 system)
  100.00% CPU
  520,386 processor cycles
  145,696 bytes consed

CL-USER> (time (ch17:reverse1 *test-list*))
Evaluation took:
  0.000 seconds of real time
  0.000000 seconds of total run time (0.000000 user, 0.000000 system)
  100.00% CPU
  260,640 processor cycles
  178,416 bytes consed

CL-USER> (time (ch17:reverse1 *test-list*))
Evaluation took:
  0.000 seconds of real time
  0.000000 seconds of total run time (0.000000 user, 0.000000 system)
  100.00% CPU
  279,822 processor cycles
  178,416 bytes consed

CL-USER> (time (ch17:reverse1 *test-list*))
Evaluation took:
  0.000 seconds of real time
  0.000000 seconds of total run time (0.000000 user, 0.000000 system)
  100.00% CPU
  264,700 processor cycles
  161,504 bytes consed

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

Как правило, эти тайминги не гарантируют достаточной надежности для маркетинговых сравнений. Их значение в первую очередь эвристическое для целей настройки.

Но я ожидал, что это относится к таймингам, а не к количеству байтов. Являются ли значения байтов, переданные time, ненадежными? Есть ли оптимизация за кулисами, которая за это отвечает? Что мне не хватает?


person ad absurdum    schedule 14.04.2019    source источник
comment
Вызывая (sb-ext:gc :full t) перед time, вы, как правило, имеете меньше различий в результатах, удаляя один источник шума в ваших измерениях.   -  person coredump    schedule 14.04.2019


Ответы (1)


Количество consing (в смысле «выделенных байтов памяти») зависит от всего:

  • это зависит от того, сколько объектов каких типов вы выделяете;
  • это зависит от точных деталей реализации распределителя, например, выделяет ли он большие куски и записывается ли «распределение» между выделением больших кусков;
  • это зависит от сборщика мусора - был ли он запущен? если да то какой? насколько волосатый GC? сам GC выделяет? как подсчитывается распределение по GC?
  • это зависит от того, выполняет ли система другое распределение, например, в других потоках, и учитывается ли это распределение или нет в вашем потоке - есть ли только один распределитель или есть распределители для каждого потока?
  • это зависит от фазы Луны и от того, является ли Плутон планетой;
  • и так далее.

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

person Community    schedule 14.04.2019