Как я могу генерировать постоянную загрузку процессора в С#, ниже 100% в течение определенного времени? Я также хотел бы иметь возможность изменить количество нагрузки через определенный промежуток времени. Как вы рекомендуете генерировать всплески использования в течение очень короткого времени?
Имитировать постоянную нагрузку процессора и шипы
Ответ 1
Во-первых, вы должны понимать, что использование ЦП всегда является средним за определенное время. В любой момент времени процессор работает, или нет. Процессор никогда не работает на 40%.
Мы можем, однако, имитировать нагрузку 40%, скажем, секунду, за счет того, что процессор работает на 0,4 секунды и спать 0,6 секунды. Это дает среднее использование 40% за эту секунду.
Сокращение до менее чем одной секунды, скажем, 100 миллисекундных кусков должны давать еще более стабильное использование.
Следующий метод будет использовать аргумент, который является желательным использованием, а затем использовать один процессор/ядро в этой степени:
public static void ConsumeCPU(int percentage)
{
if (percentage < 0 || percentage > 100)
throw new ArgumentException("percentage");
Stopwatch watch = new Stopwatch();
watch.Start();
while (true)
{
// Make the loop go on for "percentage" milliseconds then sleep the
// remaining percentage milliseconds. So 40% utilization means work 40ms and sleep 60ms
if (watch.ElapsedMilliseconds > percentage)
{
Thread.Sleep(100 - percentage);
watch.Reset();
watch.Start();
}
}
}
Я использую stopwatch здесь, потому что он более точен, чем TickCount, но вы также можете использовать его и использовать вычитание, чтобы проверить, достаточно ли вы запустили достаточно.
Следует иметь в виду две вещи:
- в многоядерных системах вам нужно будет создать один поток для каждого ядра. В противном случае вы увидите только один процессор/ядро, использующее грубую "процентную долю/количество ядер".
- Thread.Sleep не очень точен. Он никогда не гарантирует времени ровно до миллисекунды, поэтому вы увидите некоторые изменения в ваших результатах.
Чтобы ответить на второй вопрос об изменении использования через определенное время, я предлагаю вам запустить этот метод по одному или нескольким потокам (в зависимости от количества ядер), а затем, когда вы хотите изменить использование, вы просто остановите эти потоки и создайте новые с новыми процентными значениями. Таким образом, вам не нужно реализовывать связь потоков, чтобы изменить percentage
работающего потока.
Ответ 2
Просто добавив ответ Isak, я позволю себе простую реализацию для многоядерности:
public static void CPUKill(object cpuUsage)
{
Parallel.For(0, 1, new Action<int>((int i) =>
{
Stopwatch watch = new Stopwatch();
watch.Start();
while (true)
{
if (watch.ElapsedMilliseconds > (int)cpuUsage)
{
Thread.Sleep(100 - (int)cpuUsage);
watch.Reset();
watch.Start();
}
}
}));
}
static void Main(string[] args)
{
int cpuUsage = 50;
int time = 10000;
List<Thread> threads = new List<Thread>();
for (int i = 0; i < Environment.ProcessorCount; i++)
{
Thread t = new Thread(new ParameterizedThreadStart(CPUKill));
t.Start(cpuUsage);
threads.Add(t);
}
Thread.Sleep(time);
foreach (var t in threads)
{
t.Abort();
}
}
Ответ 3
Для равномерного стресса: Исак Саво ответил с легкой настройкой
int percentage = 80;
for (int i = 0; i < Environment.ProcessorCount; i++)
{
(new Thread(() = >
{
Stopwatch watch = new Stopwatch();
watch.Start();
while (true)
{
// Make the loop go on for "percentage" milliseconds then sleep the
// remaining percentage milliseconds. So 40% utilization means work 40ms and sleep 60ms
if (watch.ElapsedMilliseconds > percentage)
{
Thread.Sleep(100 - percentage);
watch.Reset();
watch.Start();
}
}
})).Start();
}
Ответ 4
Каждый раз, когда вы должны установить переменную cpuUsageIncreaseby. например:
1- Cpu% увеличение нa > cpuUsageIncreaseby% в течение одной минуты. 2- Спуститься до 0% в течение 20 секунд. 3- Перейти к этапу 1.
private void test()
{
int cpuUsageIncreaseby = 10;
while (true)
{
for (int i = 0; i < 4; i++)
{
//Console.WriteLine("am running ");
//DateTime start = DateTime.Now;
int cpuUsage = cpuUsageIncreaseby;
int time = 60000; // duration for cpu must increase for process...
List<Thread> threads = new List<Thread>();
for (int j = 0; j < Environment.ProcessorCount; j++)
{
Thread t = new Thread(new ParameterizedThreadStart(CPUKill));
t.Start(cpuUsage);
threads.Add(t);
}
Thread.Sleep(time);
foreach (var t in threads)
{
t.Abort();
}
//DateTime end = DateTime.Now;
//TimeSpan span = end.Subtract(start);
//Console.WriteLine("Time Difference (seconds): " + span.Seconds);
//Console.WriteLine("10 sec wait... for another.");
cpuUsageIncreaseby = cpuUsageIncreaseby + 10;
System.Threading.Thread.Sleep(20000);
}
}
}