Проблема даже с попыткой сделать это заключается в том, что это трудная проблема. Во-первых, как вы вообще надежно отслеживаете загрузку ЦП и диска? Нечастая выборка ЦП даст плохую картину того, что на самом деле происходит, а выборка использования диска еще сложнее. Во-вторых, какова степень детализации ваших задач и как часто вы можете быстро менять количество выполняемых задач. В-третьих, вещи быстро меняются со временем, поэтому вам нужно применить какую-то фильтрацию к вашим наблюдениям. В-четвертых, идеальное количество потоков будет зависеть от процессора, на котором фактически выполняется код. В-пятых, если вы выделите слишком много потоков, вы будете метаться между ними вместо того, чтобы выполнять полезную работу.
См. http://msdn.microsoft.com/en-us/magazine/ff960958.aspx для обсуждения того, как пул потоков в .NET справляется со сложной задачей определения количества используемых потоков.
Вы также можете использовать рефлектор и взглянуть на код, который TPL использует для распределения потоков и предотвращения ненужного переключения контекста — он сложный и даже не принимает во внимание доступ к диску!
Вместо этого вы можете попробовать выполнить задачи в потоке с более низким приоритетом (создание собственного TaskScheduler
, который запускает потоки с приоритетом ниже нормального, на самом деле довольно просто). По крайней мере, это гарантирует, что вы сможете запустить ЦП на 100%, не влияя на остальную часть системы. Игра с приоритетами потоков сама по себе чревата проблемами, но если это чисто фоновая задача, это может быть просто и может помочь.
Часто, однако, использование диска является настоящим виновником, когда дело доходит до других приложений, страдающих от рук одного жадного приложения. Windows может легко распределять ЦП между приложениями, но когда речь идет о относительно медленном доступе к диску, это совсем другое дело. Вместо того, чтобы пытаться динамически регулировать количество запущенных потоков, вам может потребоваться просто ограничить ваше приложение, чтобы оно не слишком часто обращалось к диску. Это то, что вы можете сделать, не меняя количество активных потоков.
Вы также можете рассматривать SetPriorityClass
как способ сообщить ОС, что ваш процесс менее важен, чем другие приложения, работающие в системе, см. Как можно увеличить приоритет ввода/вывода процесса? для получения дополнительной информации. Но это предполагает, что весь ваш процесс менее важен, а не только эта его часть.
person
Ian Mercer
schedule
14.09.2010