0 / 0 / 0
Регистрация: 01.06.2014
Сообщений: 4
1
.NET 4.x

Массив потоков. Максимально быстрое выполнение

01.06.2014, 13:14. Показов 1896. Ответов 7
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Добрый день.

Стоит такая задача:
Максимально быстро циклически выполнять определенный метод в течение некоторого времени.
Сам метод может выполняться 100-300 мс.
В идеале необходимо получать результат выполнения каждую миллисекунду.
То есть нужно получить некое плотное покрытие из результатов с интервалом не более 1 мс.

Реально ли это сделать?

Для проверки сделал такое консольное приложение:
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
using System;
using System.Collections.Generic;
using System.Threading;
 
namespace ConsoleApplication1
{
    class Program
    {
        static void Main()
        {
            GetTime(); // получаем время начала выполнения программы
 
            var threads = new List<Thread>();
 
            for (var i = 0; i++ < 100; )        //сделал так в надежде, что такая инициализация поможет
                threads.Add(new Thread(Dummy)); //сэкономить время в следующем цикле
                                                
            for (var i = 0; i < 100; i++)
                threads[i].Start();
 
            Console.Read();
        }
 
        static void Dummy()
        {
            Thread.Sleep(250); //некая функция, которая выполняется около 250 мс
            GetTime();         //логируем время получения результата
        }
 
        static void GetTime()
        {
            Console.WriteLine(DateTime.Now.ToString("ss,fff"));
        }
    }
}
В итоге (см.аттач) получаю результат мгновенно несколько раз подряд, но затем наступает некая циклическая задержка, которая всё портит. Возникают "дыры" в покрытии.
То ли код плохой, то ли это закономерные накладные расходы.
Вот как от нее избавиться не пойму.

Что пробовал:
1) Использовать Task и Parralel.For вместо Thread, раз уж доступен .NET 4.5 - стало только хуже. Видимо оно как-то там само по себе решает как ему оптимальнее выполняться, но задержки только возросли.
2) Помещать цикл в цикл. И пробовал генерить в цикле потоки, которые уже генерят потоки с циклами.
3) Задавать смещение во времени с помощью Thread.Sleep в надежде, что зеленые участки перекроются и я получу хоть какое-то равномерное покрытие.

Ничего не помогло. "Дыры" так и остаются, а их длительность почти не уменьшается.

Бьюсь уже который день. Помогите, пожалуйста!
Миниатюры
Массив потоков. Максимально быстрое выполнение  
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
01.06.2014, 13:14
Ответы с готовыми решениями:

Максимально быстрое чтение очень большого файла
Добрый день, задача прочитать очень большой файл (1GB-10GB+). Нужно провести операцию с каждой...

Максимально быстрое определение количество вхождений подстроки в строку
Добрый день! Необходимо максимально быстро подсчитывать количество пробелов в строке. Написал...

Максимально быстрое копирование и инициализация матрицы, краш кода
Написал такую либу (тут не совсем Си, но задача была, сделать максимально быстрое копирование и...

Быстрое выполнение скрипта на локалхосте и долгое на сервере
Здравствуйте уважаемые пользователи! Недавно столкнулся с такой проблемой - скрипт на локалхосте...

7
47 / 39 / 15
Регистрация: 28.09.2012
Сообщений: 818
01.06.2014, 16:35 2
попробуй делать паузы на 1мс в методе нового потока. да и если нужно то можно в каждом новом потоке добавлять еще на 1 мс паузы. тогда ответы будут не одновременно от всех потоков а спустя 1мс от каждого потока
0
Неадекват
1494 / 1232 / 246
Регистрация: 02.04.2010
Сообщений: 2,793
01.06.2014, 18:18 3
1. Чем обусловлено время выполнения функции 250мс - есть ли возможность ускорить?
2. Какие ресурсы выделены на задачу?
3. DateTime.Now - обновляется раз примерно в 16 мс, возможно ошибка в измерении.
0
0 / 0 / 0
Регистрация: 01.06.2014
Сообщений: 4
01.06.2014, 21:22  [ТС] 4
Цитата Сообщение от freeba Посмотреть сообщение
1. Чем обусловлено время выполнения функции 250мс - есть ли возможность ускорить?
Функция что-то отправляет на удаленный сервер и возвращает ответ. Время выполнения зависит от сервера и может колебаться. Повлиять никак нельзя.
Цитата Сообщение от freeba Посмотреть сообщение
Какие ресурсы выделены на задачу?
Можно пожертвовать все имеющиеся ресурсы. То есть пусть всё "висит", но покрытие будет максимальным.
Цитата Сообщение от freeba Посмотреть сообщение
DateTime.Now - обновляется раз примерно в 16 мс, возможно ошибка в измерении.
А можно ли как-то иначе измерить? или от этого никуда не деться?
0
0 / 0 / 0
Регистрация: 01.06.2014
Сообщений: 4
01.06.2014, 23:11  [ТС] 5
Почитал msdn, нашел метод Stopwatch.GetTimestamp. Можно ли его использовать для замеров вместо DateTime.Now, если Stopwatch.IsHighResolution возвращает истину?
Всё равно получаю картину с циклической задержкой
Миниатюры
Массив потоков. Максимально быстрое выполнение  
0
Неадекват
1494 / 1232 / 246
Регистрация: 02.04.2010
Сообщений: 2,793
02.06.2014, 11:03 6
Цитата Сообщение от Obs Посмотреть сообщение
нашел метод Stopwatch.GetTimestamp.
И чем он вас не устроил? Он возвращает количество тактов, для получения миллисекунд используйте конструкцию:
C#
1
2
3
4
var stopwatch = System.Diagnostics.Stopwatch.StartNew();
// Some code here...
stopwatch.Stop();
Console.WriteLine(stopwatch.Elapsed);
Судя по картинке - запрос идет чаще чем раз в миллисекунду...
0
0 / 0 / 0
Регистрация: 01.06.2014
Сообщений: 4
02.06.2014, 18:07  [ТС] 7
freeba, использовал эту конструкцию и условно разделил "пул" из 40 потоков на 8 параллельно выполняющихся частей:

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
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
 
namespace ConsoleApplication1
{
    class Program
    {
        public static List<Stopwatch> sws = new List<Stopwatch>();
        public static List<Thread> threads = new List<Thread>();
 
        static void Main()
        {
            for (var i = 0; i < count; i++)
            {               
                threads.Add(new Thread(Dummy));
                sws.Add(new Stopwatch());
            }
                        
            for(int i = 0; i < count; i++) sws[i].Start();
 
            new Thread( () => { for(int i = 0; i < 5; i++) threads[i].Start(i); }).Start();
            new Thread( () => { for(int i = 5; i < 10; i++) threads[i].Start(i); }).Start();
            new Thread( () => { for(int i = 10; i < 15; i++) threads[i].Start(i); }).Start();
            new Thread( () => { for(int i = 15; i < 20; i++) threads[i].Start(i); }).Start();
            new Thread( () => { for(int i = 20; i < 25; i++) threads[i].Start(i); }).Start();
            new Thread( () => { for(int i = 25; i < 30; i++) threads[i].Start(i); }).Start();
            new Thread( () => { for(int i = 30; i < 35; i++) threads[i].Start(i); }).Start();
            new Thread( () => { for(int i = 35; i < 40; i++) threads[i].Start(i); }).Start();
            
            Console.Read();
        }
 
        static void Dummy(object data)
        {
            int i = (int)data;
            Thread.Sleep(250); //некая функция, которая выполняется около 250 мс
            sws[i].Stop();
            Console.WriteLine(sws[i].ElapsedMilliseconds.ToString());
        }
    }
}
Всё равно в итоге нет равномерности
Миниатюры
Массив потоков. Максимально быстрое выполнение  
0
Неадекват
1494 / 1232 / 246
Регистрация: 02.04.2010
Сообщений: 2,793
02.06.2014, 20:21 8
Цитата Сообщение от Obs Посмотреть сообщение
Всё равно в итоге нет равномерности
Тут уж придется выбирать - равномерность или многопоточность, менеджером потоков windows вручную управлять нельзя, когда он соизволит запустить поток, тогда и будет.
Но попробуйте выставить приоритет реального времени.
0
02.06.2014, 20:21
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
02.06.2014, 20:21
Помогаю со студенческими работами здесь

Как определять, сколько максимально потоков можно запускать?
Здравствуйте. Есть класс. Он накапливает в себе задания на отправку запросов, а потом разом,...

Быстрое сохранение,загрузка и по нажатию клавиш выполнение действий
Добрый день, возникла трудность с написанием программы. Как реализовать быструю загрузку и...

Поочередное выполнение потоков
Есть задача из основного потока вызываются 2 дополнительных для вывода информации на экран 10 раз...

Параллельное выполнение потоков
Привет всем. Знаю что тема избитая уже, но что то не выходит все равно. Суть в том что в...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru