Является ли 16 миллисекунд необычно большим промежутком времени для разблокированного потока, работающего в Windows, для ожидания выполнения? - PullRequest
3 голосов
/ 30 ноября 2011

Недавно я проводил некоторые глубокие проверки синхронизации приложения DirectShow, которое есть в Delphi 6, с использованием компонентов DSPACK.В качестве части моей диагностики я создал класс Critical Section, который добавляет функцию тайм-аута к обычному объекту Critical Section, который есть в большинстве языков программирования Windows.Если время между first Acquire () и last match Release () превышает X миллисекунд, создается исключение.

Первоначально я установилтайм-аут в 10 миллисекунд.Код, который я обернул в критических разделах, довольно быстр, используя в основном перемещения памяти и заполняет большинство операций, содержащихся в защищенных областях.К моему большому удивлению, я получал довольно частые тайм-ауты в казалось бы случайных частях кода.Иногда это происходило в блоке кода, который выполняет итерацию списка буферов и выполняет определенные быстрые операции в последовательности, иногда в крошечных разделах защищенного кода, которые выполняли очистку флага только между вызовами Acquire () и Release ().Единственная закономерность, которую я заметил, - это то, что длительности, обнаруженные при истечении времени ожидания, были сосредоточены на медианном значении около 16 миллисекунд.Очевидно, что в последнем примере вхождения, о котором я упоминал выше, требуется огромное количество времени для установки флага.

Итак, мои вопросы:

1) Возможно ли управление потоками WindowsЗачем достаточно часто (примерно раз в несколько секунд) выключать разблокированный поток и не возвращаться к нему в течение 16 миллисекунд или дольше?

2) Если это разумный сценарий, какие шаги я могу предпринять, чтобы уменьшить это вхождение, и мне следует рассмотреть вопрос о повышении приоритетов моего потока?

3) Если это не разумный сценарий, на что еще мне следует обратить внимание или попробовать в качестве метода анализа для диагностики реальной проблемы?

Примечание. Я работаю в Windows XP наIntel i5 Quad Core с 3 ГБ памяти.Кроме того, причина, по которой мне нужно быть быстрым в этом коде, связана с размером буфера в миллисекундах, который я выбрал в своих графах фильтров DirectShow.Чтобы сохранить минимальную задержку, аудио буферы в моем графике доставляются каждые 50 миллисекунд.Поэтому любая операция, которая занимает значительную долю этого времени, вызывает беспокойство.

Ответы [ 3 ]

4 голосов
/ 30 ноября 2011

Приоритеты потоков определяют, когда будут запущены готовые потоки.Однако есть механизм предотвращения голода.Есть так называемый Balance Set Manager, который просыпается каждую секунду и ищет готовые потоки, которые не запускались в течение 3-4 секунд, и если он есть, он повысит свой приоритет до 15 и увеличит вдвоенормальный квант.Он делает это не более чем для 10 потоков одновременно (в секунду) и одновременно сканирует не более 16 потоков на каждом уровне приоритета.В конце кванта повышенный приоритет падает до своего базового значения.Вы можете узнать больше в книгах по Windows Internals.

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

2 голосов
/ 01 декабря 2011

Прежде всего, я не уверен, является ли Delphi Now хорошим выбором для измерений с точностью до миллисекунды.GetTickCount и QueryPerformanceCoutner API был бы лучшим выбором.

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

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

2 голосов
/ 30 ноября 2011

звучит как нормальное поведение окон относительно разрешения таймера, если вы явно не выберете некоторые из высокоточных таймеров. Некоторые детали в этой ссылке MSDN

...