Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.78/9: Рейтинг темы: голосов - 9, средняя оценка - 4.78
 Аватар для jahtemg
19 / 21 / 12
Регистрация: 24.06.2016
Сообщений: 71
.NET 4.x

Выполнение "асинхронного" кода на нескольких ядрах

07.11.2016, 15:11. Показов 2001. Ответов 12
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Вопрос таков:

Насколько мне известно, код использующий Begin*/End* на самом деле не выполняется на нескольких ядрах, а только на одном (т.е. максимальная загрузка ЦП, если процессор имеет 4 ядра - 25%).

Хотелось бы узнать, как вы с этим боритесь. Интересно то, что если создать как минимум 4 обычных Thread, и запустить в них бесконечный цикл (разумеется, без всяких там Thread.Sleep), то загрузка ЦП будет вполне себе достигать 100%.

Речь, в основном, идет о коде сетевых приложений (серверах).
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
07.11.2016, 15:11
Ответы с готовыми решениями:

Параллельное выполнение данного кода на 4-х ядрах
Необходимо, чтобы данный участок кода выполнялся параллельно на 4 ядрах. Как это сделать? Я сделал следующим образом, но у меня всё...

Запуск gunicorn на нескольких ядрах
Добрый вечер коллеги! запускаем приложение python при помощи gunicorn (Django) /usr/bin/gunicorn --workers 2 project.wsgi -b...

Как сделать независимое выполнение нескольких фрагментов кода?
В базе данных есть несколько записей, содержащих php код. Этот код нужно выполнить независимо. То есть один код никак не должен влиять на...

12
Неадекват
 Аватар для freeba
1501 / 1237 / 248
Регистрация: 02.04.2010
Сообщений: 2,807
07.11.2016, 16:17
Все просто - TPL
1
 Аватар для jahtemg
19 / 21 / 12
Регистрация: 24.06.2016
Сообщений: 71
07.11.2016, 17:40  [ТС]
Спасибо, freeba, но меня больше интересует как это делается более сложными способами (как говорится, как под капотом).
0
Неадекват
 Аватар для freeba
1501 / 1237 / 248
Регистрация: 02.04.2010
Сообщений: 2,807
07.11.2016, 17:59
Под капотом те же Thread из ThreadPool. В любом случае реализацию никто не мешает посмотреть - исходники открыты. По крайней мере для .NET Core.
0
Эксперт .NET
 Аватар для insite2012
5548 / 4311 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
07.11.2016, 17:59
Цитата Сообщение от jahtemg Посмотреть сообщение
(как говорится, как под капотом
Тогда уточните, что вам требуется - параллельность данных или параллельность задач. В зависимости от цели используются разные приемы.
0
 Аватар для jahtemg
19 / 21 / 12
Регистрация: 24.06.2016
Сообщений: 71
07.11.2016, 18:43  [ТС]
Конкретная, хоть и надуманая задача:

Нужно сделать сервер (эмулятор) онлайн игры (мморпг).

Есть класс, отвечающий за храниение хэндлеров пакетов (классика, ushort опкод и делегат, собственно на метод-обработчик логики).

Дело в том, что обрабатывать всё это желательно сразу на нескольких ядрах, т.к. есть некоторая возможность, что сервер будет жрать весьма значитальное количество ресурсов ЦП (разумеется, не только ЦП).

Допустим, у нас есть контекст клиента (сессия), который использует BeginReceive/EndReceive/BeginSend/EndSend. Из EndReceive (то что получено сервером от игрового клиента) мы вызываем метод в классе, который хранит делегаты на методы-обработчики, допустим,

C#
1
var handler = PacketManager.GetHandler(0x1234);
Затем, просто вызываем обработчик

C#
1
handler(myPacket);
Естественно, все обработчики будут выполнятся на одном ядре, как я и писал выше. А это значит, что если метод-обработчик весьма ресурсоемок, то результат - высокая нагрузка на 1 ядро ЦП (допустим, аж 25%), а этого, теоретически, может быть и недостаточно для поддержания геймплея без задержек.


Мои вариант:
Запустить некоторое количество потоков, из которых запускать контексты клиента. Разумеется, с синхронизацией нужно будет изрядно помахаться...

Собственно, как вы бы решили эту проблему ?
0
Неадекват
 Аватар для freeba
1501 / 1237 / 248
Регистрация: 02.04.2010
Сообщений: 2,807
07.11.2016, 19:12
jahtemg, Элементарная задача. Вешаем асинхронный обработчик запросов, т.е. каждый запрос будет обрабатываться в отдельном таске, а для синхронизации хватит обычного ConcurrentDictionary. Таким образом за нагрузку на ядра будет отвечать TPL.
0
 Аватар для jahtemg
19 / 21 / 12
Регистрация: 24.06.2016
Сообщений: 71
07.11.2016, 19:43  [ТС]
Меня интересуют именно варианты решения задачи без TPL.
0
Неадекват
 Аватар для freeba
1501 / 1237 / 248
Регистрация: 02.04.2010
Сообщений: 2,807
07.11.2016, 20:16
jahtemg, а какая разница? Вместо тасков можно треды создавать - принцип один.
0
 Аватар для jahtemg
19 / 21 / 12
Регистрация: 24.06.2016
Сообщений: 71
08.11.2016, 03:26  [ТС]
Собственно, мой вариант - верный ? ConcurrentDictionary для синхронизации ? Может вы имели в виду ConcurrentQueue ?
0
Неадекват
 Аватар для freeba
1501 / 1237 / 248
Регистрация: 02.04.2010
Сообщений: 2,807
08.11.2016, 09:59
Цитата Сообщение от jahtemg Посмотреть сообщение
Собственно, мой вариант - верный ? ConcurrentDictionary для синхронизации ? Может вы имели в виду ConcurrentQueue ?
Эм, плохо представляю как приспособить очередь под хранение сессии.

Набросал пример с асинхронным сервером, разница между использованием тасков и потоков для обработки - одна строка.
C#
1
2
Task.Run(() => Worker(socket)); //Таски
ThreadPool.QueueUserWorkItem(new WaitCallback(WorkerThread), socket); //Потоки
Производительность примерно одинаковая, но микрософт уже давно рекомендует использовать TPL.

PS: Это тестовый пример - в боевых условиях, сокеты не переподключаются на каждый запрос.
Вложения
Тип файла: 7z CF.Test.7z (36.3 Кб, 5 просмотров)
0
 Аватар для jahtemg
19 / 21 / 12
Регистрация: 24.06.2016
Сообщений: 71
08.11.2016, 11:58  [ТС]
Для хранения и управления сессиями я обычно делаю отдельный класс.
Спасибо за код... Но я имел в виду то, что я думаю что очень желательно ограничивать количество этих самых потоков в которых будут запускаться воркеры сессии (в моем случае, просто вызов session.Start()).

Про ConcurrentQueue - я имел в виду то, что можно принятые подключения добавлять в очередь (SessionWorkItem) и затем оттуда вытягивать и запускать в одном из предварительно созданных потоках (вполне типичный producer-consumer?).
0
Неадекват
 Аватар для freeba
1501 / 1237 / 248
Регистрация: 02.04.2010
Сообщений: 2,807
08.11.2016, 13:01
А зачем? На MSDN рекомендуют не сильно увлекаться ручной установкой ограничений.

Пул потоков предоставляет новые рабочие потоки или потоки завершения ввода-вывода по запросу, пока не будет достигнут минимум для каждой категории. При достижении минимума пул потоков может создавать дополнительные потоки в этой категории или ожидать завершения некоторых задач. Начиная с .NET Framework 4 пул потоков создает и уничтожает рабочие потоки в целях оптимизации пропускной способности, которая определяется как количество задач, завершаемых за единицу времени. Слишком малое количество потоков может препятствовать оптимальному использованию доступных ресурсов, тогда как слишком большое их количество может усиливать конкуренцию за ресурсы.

Можно использовать SetMinThreads метод для увеличения минимального количества потоков. Однако необоснованное увеличение этих значений может привести к снижению производительности. Если одновременно запускается слишком много задач, все они могут выполняться слишком медленно. В большинстве случаев пул потоков работает наилучшим образом, если он использует собственный алгоритм выделения потоков.
Цитата Сообщение от jahtemg Посмотреть сообщение
Про ConcurrentQueue - я имел в виду то, что можно принятые подключения добавлять в очередь (SessionWorkItem) и затем оттуда вытягивать и запускать в одном из предварительно созданных потоках (вполне типичный producer-consumer?).
Принятые подключения проще заносить в список и вешать event отслеживающий поступление данных. Как только данные поступили - их сразу на обработку в пул потоков. Вроде так проще.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
08.11.2016, 13:01
Помогаю со студенческими работами здесь

Вычисление функции с использованием OpenMP на нескольких ядрах
Дана функция y=\frac{{x}^{2}-7x+10}{{x}^{2}-8x+12} на промежутке . Нужно вычислить её значения и записать время выполнения программы на 1,...

Ожидание выполнение асинхронного метода
Всем привет. Помогите разобраться с асинхронным программированием. Пишу приложение для windows store Есть класс. В нем два асинхронных...

Как прекратить выполнение асинхронного метода
Есть форма. По событию mouseUp исполняется следующий код: _isDragging = false; if (_isClickOnly) { ...

Как дождаться выполнение асинхронного Post запроса?
Имеется код: async public void SearchWall(string text) { try { ...

Как правильно дождаться завершения асинхронного кода promise?
Доброго всем. Начинаю учить js, появилась проблема: let ReadAppsDir = new Promise((ok, fail) => { fs.readdir(appsdir, (err,...


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

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Новые блоги и статьи
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка. Рецензия / Мнение Это мой обзор планшета X220 с точки зрения школьника. Недавно я решила попытаться уменьшить свой. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru