powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Многопоточность - исследование длительности квантов времени
25 сообщений из 40, страница 1 из 2
Многопоточность - исследование длительности квантов времени
    #39966239
DmSer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Многопоточность - исследование длительности квантов времени

В развлекательных целях разработал программу для измерения длительности квантов времени. В программе необходимо указать количество запускаемых потоков, а в диспетчере задач выполнить привязку процесса к одному ядру. Затем нажать кнопку "Запустить потоки на 5 секунд".

Код метода TCalcQuantThread.Execute:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
procedure TCalcQuantThread.Execute;
var
  StartTicks, BreakDiff, QuantDiff, CurQuantTime: Int64;
  PrevTicks, CurTicks, CurQuantStart: Int64;
  Freq: Int64;
begin
  QueryPerformanceFrequency(Freq);
  QueryPerformanceCounter(StartTicks);
  PrevTicks := StartTicks;
  CurQuantStart := StartTicks;
  BreakDiff := 5 * Freq;
  QuantDiff := Round(0.001 * Freq);
  CurQuantTime := 0;
  repeat
    QueryPerformanceCounter(CurTicks);
    Inc(LoopCount);
    if CurTicks - PrevTicks > QuantDiff then
    begin // Если разница оказалась больше 1 мс, значит ОС приостанавливала
          // работу потока и теперь начался отсчёт нового кванта
      AddToWorkList(CurQuantTime / Freq); // Сохраняем время работы потока
      AddToNotWorkList((CurTicks - PrevTicks) / Freq); // Сохраняем время простоя потока
      CurQuantStart := CurTicks;
      CurQuantTime := 0;
    end else
      CurQuantTime := CurTicks - CurQuantStart;
    PrevTicks := CurTicks;
  until (CurTicks - StartTicks) > BreakDiff;
  if CurQuantTime > 0 then // Обрабатываем длительность последнего кванта
    AddToWorkList(CurQuantTime / Freq);
  IsFinish := True;
end;



Ссылка на архив с программой (исходники + исполняемый файл):


Вот такие выводы у меня получились:
1) привязка потока к ядру процессора не является постоянной. Это хорошо видно, если запустить только один поток и не привязывать его к ядру в диспетчере задач. При этом часто оказываются загружены несколько ядер (суммарная загрузка не более 100%).
2) ОС старается распределить загрузку по всем доступным ядрам. Если запущены 4 вычислительных потока, то ОС распределит нагрузку по 4-м ядрам (у меня 4-ядерный процессор без гипертрединга).
3) если за одном ядре запущен только один такой поток (вычислительный), то определить длительность кванта времени не удаётся. Предполагаю, что поток отработал свой квант (предположим 50 мс), затем ОС его усыпила, но поскольку нет других потоков, которым нужен процессор, ОС тут же его пробуждает.
4) квант времени - не такая уж маленькая величина. Типичная длительность кванта времена на моём ноутбуке с Intel Core i3 (поколение не знаю) составляет 95мс. Подчеркну - именно для потоков, выполняющих тяжёлые вычислительные задачи (т.е. грузят процессор на 100% и сами по своей воле не засыпают).
5) если запускать потоки с максимальным приоритетом на одном ядре, то происходит их последовательное выполнение. Т.е. если мы создадим 10 потоков с максимальным приоритетом на одном ядре, то будем ждать их завершения 50 сек (примерно так, но тут я недостаточно исследовал :)
6) с помощью функции GetTickCount невозможно решить данную задачу (пытался с ней вначале), т.к. она начинает возвращать новое значение лишь спустя 16 мс. Такая у неё разрешающая способность. А у функции QueryPerformanceCounter точность гораздо выше: менее 1 микросекунды.


Разработанный пример может оказаться полезен начинающим программистам, изучающим тему многопоточности.
Особенности программы следующие:
1) За уничтожение объекта потока отвечает форма TForm1. Объект потока не уничтожается автоматически при завершении работы метода Execute. При завершении работы потока выставляется поле "IsFinish := True", которое анализируется в событии таймера "TForm1.Timer1Timer".
2) Программа может создать любое количество потоков, которое укажет пользователь (в разумных пределах). Каждому потоку назначается порядковый номер, который передаётся при создании объекта потока с помощью конструктора "TCalcQuantThread.Create"
3) Для хранения ссылок на созданные объекты потоков используется список FList: TList.
4) При срабатывании таймера осужествляется обход списка FList в обратном порядке и для всех потоков, у которых выставлено IsFinish=True, осуществляется вывод собранной информации в компонент Memo1: TMemo, после чего объект потока уничтожается (T.Free), а соответствующий ему элемент удаляется из списка FList.
5) В том случае, если пользователь решил закрыть программу раньше, чем окончатся 5 секунд, в событии TForm1.FormDestroy произойдёт обход списка FList и для каждого объекта потока последовательно будет вызван метод Free. Посколько все потоки выполняются 5 секунд и заканчиваются почти в одно время, то вызов метода Free займет время только для самого первого элемента списка FList. Остальные вызовы Free выполнятся моментально, т.к. к этому времени все потоки уже завершат свою работу.
...
Рейтинг: 0 / 0
Многопоточность - исследование длительности квантов времени
    #39966250
shalamyansky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Приятное исследование, спасибо.
DmSer

6) с помощью функции GetTickCount невозможно решить данную задачу (пытался с ней вначале), т.к. она начинает возвращать новое значение лишь спустя 16 мс. Такая у неё разрешающая способность.

См. SetSystemTimeAdjustment
Это разрешение можно задавать, начиная со 100 нс. Вроде бы. Так написано, можете попробовать.
...
Рейтинг: 0 / 0
Многопоточность - исследование длительности квантов времени
    #39966256
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DmSer
она начинает возвращать новое значение лишь спустя 16 мс.

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

Эксперимент показал, что сферический конь в вакууме ведет себя всегда одинаково.

ЗЫ. Я тоже этим игрался, когда мне нужна была быстрая реакция при общении с чувствительной железкой.
...
Рейтинг: 0 / 0
Многопоточность - исследование длительности квантов времени
    #39966258
s62
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DmSer,

на сайте MS пишут, что промежуток времени, который выделяется потоку (time slice) - примерно 20 мс.
https://docs.microsoft.com/en-us/windows/win32/procthread/multitasking
...
Рейтинг: 0 / 0
Многопоточность - исследование длительности квантов времени
    #39966260
misha mike
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DmSer, все это можно было прочитать в книге Руссиновича и без экспериментов :)
...
Рейтинг: 0 / 0
Многопоточность - исследование длительности квантов времени
    #39966261
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
shalamyansky
См. SetSystemTimeAdjustment
Это разрешение можно задавать, начиная со 100 нс. Вроде бы. Так написано, можете попробовать.

Эта функция совсем для других целей. Чтобы изменить точность GetTickCount нужно использовать функцию timeBeginPeriod.
...
Рейтинг: 0 / 0
Многопоточность - исследование длительности квантов времени
    #39966263
DmSer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
s62
DmSer,

на сайте MS пишут, что промежуток времени, который выделяется потоку (time slice) - примерно 20 мс


Я тоже ожидал примерно такого значения. А по факту чаще 95 мс наблюдаю :)
...
Рейтинг: 0 / 0
Многопоточность - исследование длительности квантов времени
    #39966265
Barmaley57
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Многопоточность - исследование длительности квантов времени
    #39966266
misha mike
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DmSer, в догонку. Безобидная на первый взгляд функция timeSetEvent (создание мультимедийного таймера) вторым параметром принимает точность таймера в миллисекундах. Так вот, это значение, как оказалось, становится длительностью кванта глобально для всей системы пока работает этот таймер.

P.S. Хех, опоздал...
...
Рейтинг: 0 / 0
Многопоточность - исследование длительности квантов времени
    #39966270
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Barmaley57,

Кстати, ты там про QIP писал. Он мог не сам менять точность, а просто использовать компонент, который меняет, TVirtualTreeView, например ;)
...
Рейтинг: 0 / 0
Многопоточность - исследование длительности квантов времени
    #39966277
Фотография defecator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Kazantsev Alexey
Barmaley57,

Кстати, ты там про QIP писал. Он мог не сам менять точность, а просто использовать компонент, который меняет, TVirtualTreeView, например ;)


про QIP и я писал лет более 10-ти назад, что он размер кванта меняет.
...
Рейтинг: 0 / 0
Многопоточность - исследование длительности квантов времени
    #39966283
Barmaley57
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я QIP случайно идентифицировал, как виновника, когда разбирался с "поехавшим" планированием потоков. Тогда меня этот прикол сильно удивил. Из-за одного приложения меняются механизмы планирования во всей системе! Мелкософты - они такие))
...
Рейтинг: 0 / 0
Многопоточность - исследование длительности квантов времени
    #39966304
misha mike
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Barmaley57
Из-за одного приложения меняются механизмы планирования во всей системе! Мелкософты - они такие))

А вы можете предложить иной способ надежного программного отсчета малых интервалов, кроме перенастройки шедулера?
...
Рейтинг: 0 / 0
Многопоточность - исследование длительности квантов времени
    #39966305
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
misha mike,

Чем вас QueryPerformanceCounter не устраивает?
...
Рейтинг: 0 / 0
Многопоточность - исследование длительности квантов времени
    #39966307
misha mike
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rgreat, всем устраивает, но измерять малый интервал -- это не то же самое, что выполнять некое действие с этим интервалом. Таймер дергает обработчик, а чтобы исполнять код каждую миллисекунду, нужно уметь переключать задачи как минимум с таким интервалом (а лучше чаще).
...
Рейтинг: 0 / 0
Многопоточность - исследование длительности квантов времени
    #39966309
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
misha mike,

Запроектируйте алгоритм так что бы это было не важно. Как уже было сказано выше Windows это не система реального времени.

Тот кто всерьез рассчитывает на обратное - любовно раскладывает сам себе грабли.
...
Рейтинг: 0 / 0
Многопоточность - исследование длительности квантов времени
    #39966311
misha mike
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rgreat
Запроектируйте алгоритм так что бы это было не важно.

Дело не в алгоритме, а в том, что в составе WinAPI есть таймер, который умеет срабатывать с периодом вплоть до миллисекунды. Реализовать такой таймер иным способом, кроме ускорения системного шедулера, -- невозможно. Microsoft не виноваты в том, что этот таймер работает именно так. Если они и виноваты в чем-то, то в том, что не написали об этом большими красными буквами в документации к безобидной на первый взгляд функции.
...
Рейтинг: 0 / 0
Многопоточность - исследование длительности квантов времени
    #39966315
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
misha mike,

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
var
  hTim: THandle;
  Delay: Int64;
begin
  hTim := CreateWaitableTimer(nil, false, nil);// создаем таймер
  Delay := -10000000;// Delay задается в сотнях наносекунд.
  SetWaitableTimer(hTim, Delay, 0, nil,nil,false); // задаем настройки
  WaitForSingleObjectEx(hTim, infinite, true);// ждем 
  ShowMessage('Прошла одна секунда');


Таймер можно сделать цикличным а вместо WaitForSingleObjectEx заюзать каллбэк.
...
Рейтинг: 0 / 0
Многопоточность - исследование длительности квантов времени
    #39966318
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Многопоточность - исследование длительности квантов времени
    #39966410
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
misha mike
rgreat
Запроектируйте алгоритм так что бы это было не важно.

Дело не в алгоритме, а в том, что в составе WinAPI есть таймер, который умеет срабатывать с периодом вплоть до миллисекунды. Реализовать такой таймер иным способом, кроме ускорения системного шедулера, -- невозможно. Microsoft не виноваты в том, что этот таймер работает именно так. Если они и виноваты в чем-то, то в том, что не написали об этом большими красными буквами в документации к безобидной на первый взгляд функции.
вы бы разобрались для начала в вопросе каким образом планировщик задач получает управление - тынц
...
Рейтинг: 0 / 0
Многопоточность - исследование длительности квантов времени
    #39966468
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DmSer
в диспетчере задач выполнить привязку процесса к одному ядру
SetThreadAffinityMask
DmSer
привязка потока к ядру процессора не является постоянной.
Чтобы не перегревать одно ядро
DmSer
При этом часто оказываются загружены несколько ядер
Дефект большой дискретизации диспетчера задач
DmSer
ОС старается распределить загрузку по всем доступным ядрам
Смотри выше. Равномерный разогрев
DmSer
Предполагаю, что поток отработал свой квант (предположим 50 мс), затем ОС его усыпила, но поскольку нет других потоков, которым нужен процессор, ОС тут же его пробуждает.
Смотри алгоритм работы планировщика
...
Рейтинг: 0 / 0
Многопоточность - исследование длительности квантов времени
    #39966478
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_
Чтобы не перегревать одно ядро

_Vasilisk_
Смотри выше. Равномерный разогрев

Нагрев проца это не забота ОС. Процы сейчас сами умеют даже частоты поднимать для отдельных ядер, если есть нагрузка и не превышается TDP.
...
Рейтинг: 0 / 0
Многопоточность - исследование длительности квантов времени
    #39966581
misha mike
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan), и каким образом прерывание от таймера противоречит сказанному мной? Что вы вообще сказать хотели?
...
Рейтинг: 0 / 0
Многопоточность - исследование длительности квантов времени
    #39966583
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
misha mike,

пардонс, промахнулся - это на это 22146059 сообщение был ответ
...
Рейтинг: 0 / 0
Многопоточность - исследование длительности квантов времени
    #39966586
misha mike
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
great, блокирующие функции типа WaitForSingleObject все равно завязаны на разрешающую способность шедулера. Они отпускают поток не мгновенно после изменения состояния ожидаемого объекта, а в лучшем случае тогда, когда отработает текущий поток, висящий на том же ядре. Да и то не факт, на ядро могут быть завязаны и другие потоки, которые тоже дождались разблокировки и квант получит один из них.

Сами сказали, что Windows -- не система реального времени, а значит не просто мгновенного, а вообще детерменированного по времени переключения контекста быть не может. В оптимистическом среднем случае это половина интервала работы шедулера. А в пессимистическом -- вообще многие секунды.

Что касается частой генерации события в цикле, то это детский сад. Мало того, что работа цикла будет прерываться другими потоками на неопределенное время, так еще и динамическое изменение частоты процессора сделает такой "таймер" неюзабельным.
...
Рейтинг: 0 / 0
25 сообщений из 40, страница 1 из 2
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Многопоточность - исследование длительности квантов времени
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]