Сейчас на форуме: tyns777 (+5 невидимых)

 eXeL@B —› Программирование —› Как управлять загрузкой процессора?
Посл.ответ Сообщение

Ранг: 129.7 (ветеран), 2thx
Активность: 0.070
Статус: Участник

Создано: 15 апреля 2010 08:39 · Поправил: Azur1d
· Личное сообщение · #1

Возникла такая задача:
Есть процессор, для упрощения картины пусть он будет одноядерный. Все потоки в системе исполняются на этом одном ядре согласно приоритетам и бла-бла-бла. Задача - сделать так, чтобы мой поток независимо от загрузки ядра, остальных потоков и их приоритетов, загружал это ядро не более чем на N%.
Понятно, что надо вставлять Sleep(T), но как вычислить T исходя из N и данных об остальных потоках?

То есть мне нужно чтобы мой поток, даже если останется на ядре вообще один (теоретически) нагружал это самое ядро не более чем на N%. Такое вообще возможно?



Ранг: 189.9 (ветеран), 334thx
Активность: 0.30
Статус: Участник

Создано: 15 апреля 2010 09:30
· Личное сообщение · #2

А кaк eй можно упрaвлять eсли этим зaнимaeтся ОС. Нa нeё можно рaзвe что повлиять кaк то или нaписaть свою ось ;)



Ранг: 129.7 (ветеран), 2thx
Активность: 0.070
Статус: Участник

Создано: 15 апреля 2010 10:04
· Личное сообщение · #3

Ну так мне и надо повлиять
Представь ситуацию: твой поток исполняется на ядре один. Если после каждой 1мс работы вызывать Sleep(1), то поток быдет работать только половину всего возможного времени -> загрузка ядра будет 50%.
Мне же нужно вычислить величину этой задержки таким образом, чтобы загрузка ядра моим потоком на превышала определенный предел. Да, я понимаю, что планировщик раздаст освободившиеся кванты времени другим потокам, но это малозначимый факт. Главное чтобы мой поток не занимал больше определенного предела.



Ранг: 189.9 (ветеран), 334thx
Активность: 0.30
Статус: Участник

Создано: 15 апреля 2010 10:46
· Личное сообщение · #4

А вообщe для чeго тaкaя тягость? Ты нa олимпиaдe чтоли )



Ранг: 129.7 (ветеран), 2thx
Активность: 0.070
Статус: Участник

Создано: 15 апреля 2010 11:55
· Личное сообщение · #5

Это на каких олимпиадах такие задачи бывают?




Ранг: 355.4 (мудрец), 55thx
Активность: 0.320
Статус: Uploader
5KRT

Создано: 15 апреля 2010 12:14 · Поправил: Coderess
· Личное сообщение · #6

0

-----
Gutta cavat lapidem. Feci, quod potui. Faciant meliora potentes




Ранг: 369.8 (мудрец), 400thx
Активность: 0.390
Статус: Участник

Создано: 15 апреля 2010 12:24
· Личное сообщение · #7

Пример кода, грузящего одно ядро на сколько надо процентов:

Code:
  1. void do_work() {
  2.          int i; for (i = 0; i < 1000000; i++) atoi("12345");
  3. }
  4.  
  5. #define MAX_CPU 40
  6.  
  7. void main(int argc, char* argv[])
  8. {
  9.          double t;
  10.          
  11.          for (;;)
  12.          {
  13.                  t = GetTickCount();
  14.                  do_work();
  15.                  t = GetTickCount() - t;
  16.                  t = (100.0 - MAX_CPU) * (/ MAX_CPU);
  17.  
  18.                  Sleep((int)t);
  19.          }
  20. }


-----
PGP key <0x1B6A24550F33E44A>





Ранг: 324.3 (мудрец), 222thx
Активность: 0.480.37
Статус: Участник

Создано: 15 апреля 2010 12:31
· Личное сообщение · #8

Azur1d
Не, при стандартном приоритете потока квант времени на поток под Windows 2000/XP составляет в районе 10 мс. Дальше, в зависимости от того, чем занята система, примерно в равной степени распределяется нагрузка... Вроде здесь не ошибаюсь, давно читал...

Одно из решений Вашей задачи - создать high-resolution timer и счетчиками PDH интерфейса или Registry интерфейса отслеживать загрузку процессора этим потоком. При превышении загрузки усыплять его. В MSDN есть Performance Counters.

-----
IZ.RU




Ранг: 189.9 (ветеран), 334thx
Активность: 0.30
Статус: Участник

Создано: 15 апреля 2010 19:10
· Личное сообщение · #9

просто зaдaчa кaкaя-то стрaннaя нe вижу в нeй прaктичeской пользы кромe опытa



Ранг: 129.7 (ветеран), 2thx
Активность: 0.070
Статус: Участник

Создано: 15 апреля 2010 20:02
· Личное сообщение · #10

Практическая польза в планировании потоков в своем приложении. Это пока из области идеи. ХЗ, может и не проканает, но попробовать явно стоит
Спасибо всем отписавшимся.

З.Ы. На всякий случай: Да, я знаю что такое синхронизация и как ей пользоваться



Ранг: 255.8 (наставник), 19thx
Активность: 0.150.01
Статус: Участник
vx

Создано: 15 апреля 2010 21:20
· Личное сообщение · #11

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



Ранг: 129.7 (ветеран), 2thx
Активность: 0.070
Статус: Участник

Создано: 15 апреля 2010 22:25
· Личное сообщение · #12

Да мне риалтаймовость вобщем-то и не нужна. В моем приложении есть разные типы потоков. У каждого свой индекс производительности (как он вычисляется отдельная песня). Допустим поток А имеет индекс производительности 40, а поток Б - 30. Если на один поток А завести один поток Б, то А будет простаивать, т.к будет ждать данные от Б. Если завести два потока Б, то поток А не справится и будут накапливаться необработаные данные. В этом случае я указываю двум потокам Б работать на 66% и получаю необходимые 20+20 попугаев.

Повторюсь - это пока все только идеи. Возможно в процессе размышления я перейду к классической синхронизации.



Ранг: 203.3 (наставник)
Активность: 0.220
Статус: Участник
UPX Killer -d

Создано: 15 апреля 2010 22:26
· Личное сообщение · #13

Насколько помню, даже при адском повторении цикла, слип(1) ниразу не загрузит процессор.
И возможны броски от 0% до 100% с простоями, если что-то вида:
for (){
sleep(N); //Для N=1 не особо заметно.
ОфигенноСложнаяПроцедура();
}

-----
Я медленно снимаю с неё UPX... *FF_User*




Ранг: 129.7 (ветеран), 2thx
Активность: 0.070
Статус: Участник

Создано: 15 апреля 2010 22:30
· Личное сообщение · #14

AlexZ, Sleep вообще не грузит процессор, она нужна чтобы выкинуть твой поток из очереди планировщика на определенное время.
Или я не понял вашу мысль?




Ранг: 2014.5 (!!!!), 1278thx
Активность: 1.340.25
Статус: Модератор
retired

Создано: 16 апреля 2010 08:22
· Личное сообщение · #15

Чутка оффтоп. Не совсем понимаю, нафига тыкать костыльный Sleep(1), когда есть вполне нормальная функция SwitchToThread().



Ранг: 481.4 (мудрец), 109thx
Активность: 0.180
Статус: Участник
Тот самый :)

Создано: 16 апреля 2010 09:12 · Поправил: Hexxx
· Личное сообщение · #16

CreateJobObject()

SetInformationJobObject(,JobObjectBasicLimitInformation,,);

LimitFlags = JOB_OBJECT_LIMIT_AFFINITY
чтобы указать ядро, а дальше:

JOB_OBJECT_LIMIT_JOB_TIME
Establishes a user-mode execution time limit for the job.
или

JOB_OBJECT_LIMIT_PROCESS_TIME
Establishes a user-mode execution time limit for each currently active process and for all future processes associated with the job.

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

AssignProcessToJobObject ()

-----
Реверсивная инженерия - написание кода идентичного натуральному




Ранг: 309.8 (мудрец), 21thx
Активность: 0.170
Статус: Участник

Создано: 16 апреля 2010 10:15
· Личное сообщение · #17

> когда есть вполне нормальная функция SwitchToThread().
Или нейтив аналог ZwYieldExecution.

-----
Shalom ebanats!




Ранг: 61.4 (постоянный), 1thx
Активность: 0.020
Статус: Участник

Создано: 16 апреля 2010 10:47
· Личное сообщение · #18

Sleep(0) отдаёт оставшийся квант времени сразу же.


 eXeL@B —› Программирование —› Как управлять загрузкой процессора?
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати