2016-05-29 5 views
3

Просто, чтобы отвлечься от комментариев о том, почему «зачем вам это нужно знать?»: Это всего лишь загадка, которую мне было любопытно, а не что-то, что мне нужно сделать по любой практической причине.Как экспериментально определить квант планирования процесса/потока?

Учитывая типичную систему POSIX [1], как бы вы создали эксперимент для определения кванта планирования [2] процесса, связанного с процессором?

[1]: а не тот, который позволяет запрашивать эту информацию через системные вызовы или/Proc интерфейс

[2]: «Планирование квант» определяются как количество времени, процесс будет работать на Процессор, не блокирующий или уступающий до запланированного времени, заканчивается, и ОС позволяет выполнять другой процесс.

+1

Обратите внимание, что процесс с более высоким приоритетом, как правило, запускается, как только он захочет (в противном случае не было бы смысла иметь более высокий приоритет). Возможно, в вашем последнем абзаце вы хотели сказать: «... до истечения запланированного времени, и ОС позволяет запустить другой процесс с одним приоритетом». –

+0

@JeremyFriesner Я думал, что в типичных системных процессах не будет упреждаться до тех пор, пока их временной срез не истёк. Я ошибаюсь? Как это работает, скажем, в Linux или FreeBSD? Несмотря на это, я отредактировал этот вопрос. –

+0

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

ответ

2

Я не уверен, насколько точно это было бы, но это может работать:

  1. Убедитесь, что ваш компьютер находится в режиме ожидания (или в режиме ожидания, как вы можете это сделать)
  2. Spawn от 2N темы (где N - количество ядер на вашем компьютере). Все эти потоки должны быть настроены так, чтобы они выполнялись с одинаковым приоритетом.
  3. Каждый из потоков должен работать бесконечным циклом, где он ничего не делает, но многократно извлекает текущее время с монотонно возрастающим увеличением времени, используя таймер с высоким разрешением (например, вызов std :: chrono :: stable_clock :: now() или аналогичный).
  4. На каждой итерации цикла каждый поток должен проверять полученное значение времени для «внезапных зазоров», то есть когда время синхронизации перескакивает от (t) до (t + n миллисекунд, причем n больше, чем обычная дельта стоимость). Эти пробелы, скорее всего, указывают период времени, когда поток был отброшен от CPU, так что другой один из потоков мог работать.
  5. В какой-то момент вычислите среднее значение размеров всех этих пробелов, и это ваша оценка квантового размера планировщика.

Обратите внимание, что это предполагает, что разрешение часов больше, чем размер кванта планировщика; если это не так (например, если вы пытаетесь использовать часы с разрешением 10 мс для измерения квантовой длины 5 мкс), то измерение квантовой длины будет затруднено AFAICT.

+2

Скорее всего, это близко, но я думаю, что он может быть сброшен в системах, где std :: chrono :: stable_clock :: now() требует syscall (так что переключатели контекста и планирование будут выполняться каждый раз через цикл, а не только после истечения времени ожидания) –

+0

Syscall не вызывает переключения на другую задачу. Это будет чрезвычайно дорогой дизайн системы. – usr

+0

Может потребоваться переключение контекста из пользовательского режима в режим ядра (и обратно), хотя .... http://stackoverflow.com/questions/9238326/system-call-and-context-switch –

2

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

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

  • В то же время запустите дополнительный поток, который устанавливает флаг завершения.

Сделайте это при множестве итераций в петле.

Если цикл завершен внутри среза времени потока, он выполнит все итерации. Если он не завершится в срезе времени потока, поток завершения будет иметь возможность прервать один из потоков цикла.

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

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

+0

В многопроцессорной системе не будет нить 2/всегда/сразу работать на доступном процессоре? –

+0

@BrennanVincent Хорошая точка - если нет других потоков, да. Я скорректировал ответ, чтобы разместить это. Очевидно, что дизайн теста может быть еще более усовершенствован, но я думаю, что основная идея, которую я предоставляю, звучит. –