Имитировать постоянную нагрузку на процессор и пики - PullRequest
41 голосов
/ 25 марта 2010

Как я могу генерировать устойчивую загрузку процессора в C #, ниже 100% в течение определенного времени? Я также хотел бы иметь возможность изменить объем загрузки после определенного периода времени. Как вы рекомендуете генерировать пики использования за очень короткое время?

Ответы [ 4 ]

55 голосов
/ 25 марта 2010

Прежде всего, вы должны понимать, что загрузка процессора всегда является средней за определенное время. В любой момент времени процессор либо работает, либо нет. Процессор никогда не работает на 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();
        }
    }
}

Я использую секундомер здесь, потому что он более точен, чем свойство TickCount , но вы также можете использовать это и использовать вычитание, чтобы проверить, долго ли вы работаете довольно.

Следует помнить две вещи:

  • в многоядерных системах вам придется создавать один поток для каждого ядра. В противном случае вы увидите, что задействуется только один процессор / ядро, дающее примерно процент использования / количества ядер.
  • Тема. Сон не очень точный. Это никогда не будет гарантировать точное время с точностью до миллисекунды, поэтому вы увидите некоторые изменения в результатах

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

16 голосов
/ 24 января 2012

Просто добавив ответ 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();
        }
   }
4 голосов
/ 02 марта 2017

Для равномерного подчеркивания: ответ Исака Саво с небольшим изменением

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();
}
1 голос
/ 07 января 2013

Каждый раз, когда вам нужно установить переменную cpuUsageIncreaseby. например:

1 - увеличение% ЦП на> 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);
                }
            }
        }
...