Синхронизация потоков

Язык Visual Basic на платформе .NET.

Модераторы: Ramzes, Sebas

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4147
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Синхронизация потоков

Сообщение Mikle » 22.11.2012 (Чт) 10:37

Программа - софт рендер, рендер таргет разделён на 4 равные части, процедура рендера одна и та же для четырёх потоков, только каждый рендерит в свой массив. Для визуализации используется API SetDiBitsToDevice, ибо она оказалась быстрее всех NET средств.
Вопрос - как синхронизировать работу потоков? Возможно ли, не сильно теряя производительность, делать это, скажем, при 60 fps?
Я пока использую общую переменную с битовыми флагами, при старте они устанавливаются в 1 для каждого потока. При рендере флаг сбрасывается в 0, после рендера поток ожидает в цикле, пока опять там не будет 1, тогда рендерит следующий кадр. Поток №0 - главный, он после рендера сначала ожидает, пока не обнулятся флаги всех потоков, потом опять устанавливает все единицы. Это работает, но наблюдаются сильные рывки, хотя в распоряжении 4 ничем другим не нагруженных ядра.
В каждом потоке есть DoEvents.

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 22.11.2012 (Чт) 10:56

Если потоки самостоятельные, то, возможно, DoEvents надо как раз убрать.
Со всякими счётчиками аккуратнее, возможно, что операции, которые кажутся атомарными, на самом деле такими не являются (как инкремент int'а в Джаве, в .NET не проверял)...

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4147
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Re: Синхронизация потоков

Сообщение Mikle » 22.11.2012 (Чт) 13:14

Qwertiy писал(а):Со всякими счётчиками аккуратнее, возможно, что операции, которые кажутся атомарными, на самом деле такими не являются

Я специально использую битовые флаги в одной Integer переменной, все операции над ней тоже 32-битные. С этим проблем не возникает.
DoEvents убрал - ничего не изменилось, добился некоторой равномерности, но fps 200 против 320-ти, когда потоки не синхронизированы. Я проверял, каждый несинхронизированный поток даёт около 320-ти fps, а стоит засинхронизировать - 200. Разница только в ожидании флага, а ждут, по идее, только опережающие потоки.

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 22.11.2012 (Чт) 13:23

Mikle писал(а):Я специально использую битовые флаги в одной Integer переменной, все операции над ней тоже 32-битные. С этим проблем не возникает.

Вот не факт... Один поток прочитал значение, другой тоже прочитал, потом каждый изменил свой бит, потом оба записали. Останется только один флаг, не оба.
Ещё раз: в Джаве простой инкримент int'а НЕ является неделимым. Хотя, теоретически его можно было бы сделать одной инструкцией процессора. Возможно, .NET делает так же - это надо проверять. А учитывая структуру Val = Val Or 1, это даже кажется логичным.

Mikle писал(а):после рендера поток ожидает в цикле

Цикл тоже процессорное время жрёт... Может, лучше как-то по другому реализовать?

Кстати, ты писал вначале про 60 fps, а теперь про 200 и 320.

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4147
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Re: Синхронизация потоков

Сообщение Mikle » 22.11.2012 (Чт) 14:07

Qwertiy писал(а):Цикл тоже процессорное время жрёт... Может, лучше как-то по другому реализовать?

Весь вопрос как.
Qwertiy писал(а):ты писал вначале про 60 fps, а теперь про 200 и 320.

Это на конкретно взятом компьютере, а 60 - на множестве целевых.

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 22.11.2012 (Чт) 14:59

Mikle писал(а):Весь вопрос как.

А ты стандартные механизмы блокировок не пробовал?

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4147
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Re: Синхронизация потоков

Сообщение Mikle » 22.11.2012 (Чт) 15:24

Qwertiy писал(а):стандартные механизмы

А есть общее описание на русском? Я на английском справочники неплохо читаю, но тут более философское, нужно общий принцып понять.

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 22.11.2012 (Чт) 16:28

Mikle писал(а):А есть общее описание на русском?

Не знаю. Это искать надо.

Admiralisimys
Постоялец
Постоялец
 
Сообщения: 318
Зарегистрирован: 01.06.2009 (Пн) 10:26

Re: Синхронизация потоков

Сообщение Admiralisimys » 22.11.2012 (Чт) 16:29

Mikle например у ЭндиТроелсена в книге "Язык программирования С# и платформа NET, 4-е издание" за 2010 (это по .NET 3.5).
От туда
Проблемы параллелизма
Одним из многочисленных неприятных аспектов многопоточного
программирования является то, что управлять способом использования потоков операционной
системой или CLR-средой практически не возможно. Например, в случае построения блока
кода, предусматривающего создание нового потока выполнения, гарантировать
немедленное выполнение этого потока никак нельзя. Скорее, такой программный код будет
лишь указывать ОС приступать к выполнению потока как можно быстрее (что обычно
зависит от планировщика потоков).
...
Что касается атомарных операций, то они всегда безопасны в многопоточной
среде. К сожалению, таких операций, которые гарантированно являются атомарными, в
библиотеках базовых классов .NET предлагается совсем не много. Даже присваивание
значения переменной экземпляра не является атомарной операцией! Если только в
документации по .NET Framework 3.5 SDK не говорится конкретно, что такая-то операция
является атомарной, следует считать ее изменчивой в отношении потоков
(thread-volatile) и предпринимать в ее отношении соответствующие меры предосторожности.


Или в .NET 4.0 варианте (Эндрю Троелсен - Язык программирования C# 2010 и платформа .NET 4).

FireFenix
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1640
Зарегистрирован: 25.05.2007 (Пт) 10:24
Откуда: Mugen no Sora

Re: Синхронизация потоков

Сообщение FireFenix » 22.11.2012 (Чт) 17:13

Mikle писал(а):Я пока использую общую переменную с битовыми флагами, при старте они устанавливаются в 1 для каждого потока. При рендере флаг сбрасывается в 0, после рендера поток ожидает в цикле, пока опять там не будет 1, тогда рендерит следующий кадр. Поток №0 - главный, он после рендера сначала ожидает, пока не обнулятся флаги всех потоков, потом опять устанавливает все единицы. Это работает, но наблюдаются сильные рывки, хотя в распоряжении 4 ничем другим не нагруженных ядра.

Т.к. поток 0 ожидает другие потоки, то очевидно, что пока не завершатся все дочернии он не будет работать. Может проблема, в том что дочерние потоки долго обрабатывают задание?

Тема без кода, слонжо понять в чём проблема - в мотдах синхронизации или в самих потоках. Может примерчик выложишь, который можно попилить?

Для синхронизации вообще есть стандартные SyncLock для классов и структур и Interlocked для целочисленных.

Mikle писал(а):А есть общее описание на русском? Я на английском справочники неплохо читаю, но тут более философское, нужно общий принцып понять.

C# -> http://www.rsdn.ru/article/dotnet/CSThreading1.xml ( + C# to VB -> http://www.developerfusion.com/tools/co ... arp-to-vb/)
Птицей Гермеса меня называют, свои крылья пожирая... сам себя я укрощаю
私はヘルメスの鳥 私は自らの羽根を喰らい 飼い慣らされる

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4147
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Re: Синхронизация потоков

Сообщение Mikle » 22.11.2012 (Чт) 17:31

Admiralisimys писал(а):например у ЭндиТроелсена в книге "Язык программирования С# и платформа NET, 4-е издание" за 2010 (это по .NET 3.5).

О! У меня есть эта книга в бумажном виде, почитаю.
FireFenix писал(а):Т.к. поток 0 ожидает другие потоки, то очевидно, что пока не завершатся все дочернии он не будет работать. Может проблема, в том что дочерние потоки долго обрабатывают задание?

У всех потоков задание практически одинаковое, разница во времени выполнения не больше 1-2%.
Статья, кажется, то, что надо!


Вернуться в Visual Basic .NET

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 12

    TopList