Гость
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Периодические задержки при выполнении программы / 13 сообщений из 13, страница 1 из 1
21.12.2015, 09:52
    #39132777
constant_ural
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Периодические задержки при выполнении программы
Выполняю задачу, требуется произвести вычисления, настолько быстро, насколько это позволяют ресурсы системы, пусть даже в ущерб всем остальным процессам.
При анализе производительности обратил внимание на следующую особенность. Как правило участки кода выполняются за более-менее одинаковое время, однако, периодически происходят непонятные мне задержки, достаточно длительные.

Я попытался сделать упрощенную модель программы, чтобы показать, то, что я имею в виду.
В программе итеративный процесс, на каждой итерации длинный внутренний цикл, имитирующий вычисления.
Далее, на каждом цикле запоминаем время окончания вычисления. После этого находим продолжительность каждой итерации. Находим среднее время итерации. После чего ищем итерации, продолжительность которых более чем в три раза выше средней и выводим их.
Если посмотреть на продолжительность итераций, то в большинстве случаев они практически одинаковые (порядка 70 мкс в моем случае).Но есть итерации,которые более чем в 8 раз больше среднего.

Следует отметить также, что процессор во время выполнения программы загружается где-то процентов на 13%. Т.е. свободных ресурсов процессора - "выше крыши", процессор используется неэффективно, и программа может быть выполнена гораздо быстрее.Пробовал увеличивать приоритет процесса и потока до максимальных - эффекта практически нет.

Вопросы:

1. Из-за чего происходят большие периодические задержки в выполнении программы, и как от них избавится ?
2. Почему процессорное время используется неэффективно, как задействовать все ресурсы процессора для выполнения программы ?

Код: c#
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.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Diagnostics;
using System.Threading;
using System.Runtime;
using System.Runtime.CompilerServices;


namespace PerfomanceTest
{
    class Program
    {
        static void Main(string[] args)
        {
            CPerfomanceTest p = new CPerfomanceTest();
            Console.ReadKey();
        }
    }

    public class CPerfomanceTest
    {
        public CPerfomanceTest()
        {                    
            List<double> lstTicks = new List<double>();
            List<double> lstTicksDelta = new List<double>();
            
            const int numIter = 100000;
            Stopwatch sw = new Stopwatch();
            sw.Start();

            for (int i = 0; i < numIter; i++)
            {                             
                //Какие-то вычисления
                for (int j = 0; j < 100000; j++) ;

                //запоминаем врмя с начала итерации в микросекундах
                lstTicks.Add(sw.ElapsedTicks * 0.1);                               
            }

            sw.Stop();

            double sum =0;
            double av = 0;

                                       
            for (int i = 1; i < numIter; i++)
            {
                //определяем продолжительность каждой итерации 
                double delta = lstTicks[i] - lstTicks[i - 1];
                lstTicksDelta.Add(delta);                             
            }

            for (int i = 1; i < numIter-1; i++)            
                sum += lstTicksDelta[i];

            
            //находим среднее время итерации
            av = sum / (numIter - 2);

            Console.WriteLine("Average time: "+av);

            Console.WriteLine("");
            Console.WriteLine("Large deviation from average:");

            for (int i = 0; i < numIter-1; i++)            
                //находим отклонение от среднего  времени выполнения итерации в три раза
                if (lstTicksDelta[i] > 3 * av)                
                    Console.WriteLine(i +" -- "+   lstTicksDelta[i]);

                            
            Console.WriteLine("Press any key");
            Console.ReadKey();

        }

    }
}
...
Рейтинг: 0 / 0
21.12.2015, 11:51
    #39132924
buser
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Периодические задержки при выполнении программы
constant_ural, ну... можно вспомнить о том кто занимается выделением процессорного времени задаче... и на что оно собственно тратится... эффективность больше связана с написанием выбором опитмальных алгоритмов, распараллеливанием вычислений... ну и еще можно поиграть с приоритетами и пр... а загрузить камень на 100% хм... это не задача...
В любом случае - ваш пример более чем не показателен...
Вот кусок старинного говнокода... попробуйте...

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


Код: c#
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.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
    class Program
    {

        static void Main(string[] args)
        {

            var cpuUsagePercent = 85;

            var cores = Environment.ProcessorCount;
            var threads = new Thread[cores];
            var stop = false;

            Console.WriteLine("vCPU cores: {0}", cores);

            for (int i = 0; i < cores; i++)
            {

               // mask = 1L << i;

                var tid = i;

                threads[i] =
                    new Thread(() =>
                                    {
                                        int loadms = (int)(1000 * (cpuUsagePercent / 100.0)), sleepms = 1000 - loadms;
                                        Stopwatch watch = Stopwatch.StartNew();

                                        do
                                        {
                                            if (watch.ElapsedMilliseconds >= loadms)
                                            {
                                                Thread.Sleep(sleepms);
                                                watch.Restart();
                                            }
                                        } while (!stop);

                                    }) { IsBackground = true, Priority = ThreadPriority.Highest, Name = "Thread_" + tid.ToString() };

            }

            threads.AsParallel().ForAll(x => x.Start());

            Console.ReadKey();

            stop = true;

            threads.Where(t => t.IsAlive)
                   .ToList()
                   .ForEach(ct => 
                                   { 
                                       if (ct.IsAlive) 
                                           ct.Join(); 
                                   });

        }
    }


...
Рейтинг: 0 / 0
21.12.2015, 12:01
    #39132934
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Периодические задержки при выполнении программы
ИМХУ это оптимизатор вообще выкинул при компиляции:
constant_ural
Код: c#
1.
2.
                //Какие-то вычисления
                for (int j = 0; j < 100000; j++) ;


Компилируй в дебаг или напиши что-нибудь осознанное с сохранением результата. Например посчитай сумму произведений i*j и результат в массив сохраняй.

Листы на массивы замени, чтобы скорость выделения памяти не мерить.

У процессора твоего сколько ядер? У тебя расчет в один поток, т.е. максимум одно ядро загрузишь.
...
Рейтинг: 0 / 0
21.12.2015, 12:42
    #39132984
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Периодические задержки при выполнении программы
В конце расчета вот это еще посмотри
Код: c#
1.
Console.WriteLine("Сборка мусора {0}/{1}/{2} раз. Память: {3} Кб", GC.CollectionCount(0), GC.CollectionCount(1), GC.CollectionCount(2), GC.GetTotalMemory(false) / 1024);
...
Рейтинг: 0 / 0
21.12.2015, 14:19
    #39133135
constant_ural
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Периодические задержки при выполнении программы
Немного изменил алгоритм по советам отвечающих:

1. Убрал листы, добавил жесткие массивы
2. Сделал максимально возможный приоритет для процесса и для потока
3. Вывел количество сборок мусора в конце

Листинг ниже.

Выводы:

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

2. Сборщик мусора похоже здесь не причем. До изменений был вывод 1/1/1 после изменений
0/0/0

Код: c#
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.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Diagnostics;
using System.Threading;
using System.Runtime;
using System.Runtime.CompilerServices;





namespace PerfomanceTest
{
    class Program
    {
        static void Main(string[] args)
        {


            CPerfomanceTest p = new CPerfomanceTest();
            Console.ReadKey();
        }
    }

    public class CPerfomanceTest
    {
        public CPerfomanceTest()
        {
           
            using (Process p = System.Diagnostics.Process.GetCurrentProcess())
            {
                p.PriorityClass = ProcessPriorityClass.RealTime;
            }

            Thread.CurrentThread.Priority = ThreadPriority.Highest;
           

           
             const int numIter = 100000;

             double[] lstTicks = new double[numIter];
             double[] lstTicksDelta = new double[numIter];
            
       
            Stopwatch sw = new Stopwatch();
            sw.Start();

            for (int i = 0; i < numIter; i++)
            {                             
                //Какие-то вычисления
                for (int j = 0; j < 100000; j++) ;

                //запоминаем врмя с начала итерации в микросекундах                                       
                lstTicks[i] = sw.ElapsedTicks * 0.1;


            }

            sw.Stop();

            double sum =0;
            double av = 0;

                                       
            for (int i = 1; i < numIter; i++)
            {
                //определяем продолжительность каждой итерации 
                double delta = lstTicks[i] - lstTicks[i - 1];                                    
                lstTicksDelta[i] = delta;
            }

            for (int i = 1; i < numIter-1; i++)            
                sum += lstTicksDelta[i];

            
            //находим среднее время итерации
            av = sum / (numIter - 2);

            Console.WriteLine("Average time: "+av);

            Console.WriteLine("");
            Console.WriteLine("Large deviation from average:");

            for (int i = 1; i < numIter-2; i++)            
                //находим отклонение от среднего  времени выполнения итерации в три раза
                if (lstTicksDelta[i] > 3 * av)                
                    Console.WriteLine(i +" -- "+   lstTicksDelta[i]);




            Console.WriteLine("Сборка мусора {0}/{1}/{2} раз. Память: {3} Кб", GC.CollectionCount(0), GC.CollectionCount(1), GC.CollectionCount(2), GC.GetTotalMemory(false) / 1024);


            Console.WriteLine("Press any key");
            Console.ReadKey();

        }




    }


}
...
Рейтинг: 0 / 0
21.12.2015, 14:32
    #39133152
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Периодические задержки при выполнении программы
Это забыл
Dima TИМХУ это оптимизатор вообще выкинул при компиляции:
constant_ural
Код: c#
1.
2.
                //Какие-то вычисления
                for (int j = 0; j < 100000; j++) ;


Компилируй в дебаг или напиши что-нибудь осознанное с сохранением результата. Например посчитай сумму произведений i*j и результат в массив сохраняй.
Если у тебя итерации продолжительные, то эмулируй их. чтобы одна итерация была хотя бы 0.1 сек. Замер в микросекундах это ни о чем. Разница на порядок может быть из-за погрешностей измерения.

Как-то так
Код: c#
1.
2.
3.
4.
5.
6.
    int[] lstRes = new int[numIter];
...
                //Какие-то вычисления
                int res = 1;
                for (int j = 0; j < 100000; j++) res = (res * j) % i;
                lstRes[i] = res;
...
Рейтинг: 0 / 0
21.12.2015, 14:50
    #39133178
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Периодические задержки при выполнении программы
Кстати на чем меряешь?
Если на ноуте - то имей ввиду, что там проц чуть помолотил, нагрелся и затупил, подостыл - опять замолотил. По моим наблюдениям только десктопные процы честно молотят в соответствии с заявленными гигагерцами. Могу ошибаться, не так уж и много я их тестил.
...
Рейтинг: 0 / 0
21.12.2015, 16:39
    #39133439
Roman Mejtes
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Периодические задержки при выполнении программы
В Windows же все процессы и потоки сбалансированы и если System начнет, что то выполнять с высоким приоритетом, твоя программа подождет
...
Рейтинг: 0 / 0
21.12.2015, 20:53
    #39133786
constant_ural
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Периодические задержки при выполнении программы
авторВ Windows же все процессы и потоки сбалансированы и если System начнет, что то выполнять с высоким приоритетом, твоя программа подождет

Но ведь я же в последней версии тестовой программы увеличил приоритет процесса и исполняемого потока, или это не столь важно ?
...
Рейтинг: 0 / 0
21.12.2015, 21:08
    #39133798
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Периодические задержки при выполнении программы
constant_uralавторВ Windows же все процессы и потоки сбалансированы и если System начнет, что то выполнять с высоким приоритетом, твоя программа подождет

Но ведь я же в последней версии тестовой программы увеличил приоритет процесса и исполняемого потока, или это не столь важно ?
Не важно. Виндовс не реал-тайм ОС. У тебя задача какая? Замеры замерить или что-то более полезное?
...
Рейтинг: 0 / 0
21.12.2015, 21:12
    #39133807
constant_ural
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Периодические задержки при выполнении программы
авторНе важно. Виндовс не реал-тайм ОС. У тебя задача какая? Замеры замерить или что-то более полезное

Скажем так, производить обработку данных. Просто иногда (редко) эти данные поступают от сервера очень быстро, и происходит "затык", а обработать их надо не так чтобы хард реал тайм но более менее без задержек. Вот я пытаюсь выяснить узкие места при работе с дотнетом в сходных условиях.
...
Рейтинг: 0 / 0
21.12.2015, 21:53
    #39133851
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Периодические задержки при выполнении программы
constant_uralавторНе важно. Виндовс не реал-тайм ОС. У тебя задача какая? Замеры замерить или что-то более полезное

Скажем так, производить обработку данных. Просто иногда (редко) эти данные поступают от сервера очень быстро, и происходит "затык", а обработать их надо не так чтобы хард реал тайм но более менее без задержек. Вот я пытаюсь выяснить узкие места при работе с дотнетом в сходных условиях.
В этой ситуации данные надо кэшировать. Делай максимально быстрое кэширование. Т.е. нужна очень быстрая постановка в очередь на обработку.
И обработку распараллеливай по возможности.
...
Рейтинг: 0 / 0
22.12.2015, 14:45
    #39134650
Arm79
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Периодические задержки при выполнении программы
GC какбэ может приоcтанавливать работу программы. Поэтому если скорость так критичная, что счет идет на микросекунды, .Net не самый удачный выбор

Прочитайте про отключение сборки мусора для критичных участков кода
GCLatencyMode
GC.TryStartNoGCRegion
...
Рейтинг: 0 / 0
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Периодические задержки при выполнении программы / 13 сообщений из 13, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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