Re[10]: Многопоточность сегодня
От: сипласплас  
Дата: 11.10.07 11:27
Оценка:
Здравствуйте, GlebZ, Вы писали:

GZ>Здравствуйте, сипласплас, Вы писали:


С>>При чем здесь сборка мусора? А между ними что будем делать с изменением ссылок в разных потоках?

GZ>А в чем проблема то? Адрес экземпляра объекта "неизменяемо". Единственный кто может его изменить — GC. Присваивание int — атомарно на аппаратном уровне. Так в чем дело?

не забывай про необходимый memory barrier
Re[10]: Многопоточность сегодня
От: сипласплас  
Дата: 11.10.07 11:29
Оценка:
Здравствуйте, remark, Вы писали:

[]

С>>Ты у себя в программе вот так спокойно делаешь с поинтерами, к которым идет доступ из разных тредов?


R>На x86 да, а почему бы и нет? Это экстремально быстро.


remark, а memory barrier? Или это я один тут параноик?

R>>>>>

R>>>
R>
Re[5]: Многопоточность сегодня
От: Кодёнок  
Дата: 11.10.07 11:42
Оценка:
Здравствуйте, eao197, Вы писали:

E>Например, механизм producer/consumer с большими объемами данных. Скажем, видеопроигрыватель, где процесс подкачки данных с диска занимает очередной буфер и заполняет его, а процесс восспроизведения не может получить доступ к буферу до окончания закачки.


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

E>Какие выигрышы (жи/ши пиши через и, а жы/шы — через ы?) даст здесь обмен сообщениями по сравнению с ожиданием на cond_var/mutex-е?


Да никаких. Речь в изначальном посте вообще-то шла о том, как современной программе загрузить десятки процессоров. Описанная тобой задача в принципе не загрузит больше двух.

Речь не идет о том, чтобы Erlang автоматически за тебя что-то сделал. Речь о том, что то же самое делается удобнее. Параллелит-то всё еще программист. Только шанс допустить ошибку куда меньше, чем забыть захватить мьютекс или захватить его на излишне долгое время и тем самым затормозить программу.

Например, какие изменения тебе нужно внести в архитектуру, чтобы проигрыватель мог послать «напоминание» и получить частично заполненный буфер, чтобы пользователь не увидел подвисания картинки, в надежде что задержка чтения временная и вот-вот все нормализуется? Сменить блокирующее ожидание сокета на свой цикл проверки, чтобы был появился шанс проверить флаг?

В архитектуре изолированных процессов, producer получает сообщение от сокета о приеме данных, и добавляет в буфер, или получает сообщение от проигрывателя, и отдает частично заполненный. Расширение делается добавлением всего одного сообщения.
Re[11]: Многопоточность сегодня
От: GlebZ Россия  
Дата: 11.10.07 11:59
Оценка:
Здравствуйте, сипласплас, Вы писали:

С>не забывай про необходимый memory barrier

А что memory barrier? Это всего лишь еще одна ссылка на тот же адрес. Даже если они будут различаться с хранящейся в OЗУ, после сборки выполнение продолжится, и будет присвоен корректный адрес. Атомарность не пострадает.
Re[6]: Многопоточность сегодня
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 11.10.07 12:05
Оценка:
Здравствуйте, Кодёнок, Вы писали:

E>>Например, механизм producer/consumer с большими объемами данных. Скажем, видеопроигрыватель, где процесс подкачки данных с диска занимает очередной буфер и заполняет его, а процесс восспроизведения не может получить доступ к буферу до окончания закачки.


Кё>Процесс подкачки данных занимает буфер и заполняет его. По окончании передает владение над ним процессу воспроизведения (в виде сообщения). Единственный выигрыш, что ожидание не надо делать вручную. Мьютекс не нужен. Состояние ожидания сообщения, и это и есть уже готовое ожидание.


Ожидание в любом случае придется делать вручную. Будет ли это mutex.acquire или receive->BUFFER_READY.

Только вот при работе с mutex-ом у тебя один системный вызов. При передаче сообщения -- несколько, поскольку сообщение нужно синхронизировать доступ к очереди сообщений.

E>>Какие выигрышы (жи/ши пиши через и, а жы/шы — через ы?) даст здесь обмен сообщениями по сравнению с ожиданием на cond_var/mutex-е?


Кё>Да никаких. Речь в изначальном посте вообще-то шла о том, как современной программе загрузить десятки процессоров. Описанная тобой задача в принципе не загрузит больше двух.


Это уже придирки.

Кё>Речь не идет о том, чтобы Erlang автоматически за тебя что-то сделал. Речь о том, что то же самое делается удобнее. Параллелит-то всё еще программист. Только шанс допустить ошибку куда меньше, чем забыть захватить мьютекс или захватить его на излишне долгое время и тем самым затормозить программу.


На основании какого опыта в Erlang вы делаете такие утверждения?

Кё>Например, какие изменения тебе нужно внести в архитектуру, чтобы проигрыватель мог послать «напоминание» и получить частично заполненный буфер, чтобы пользователь не увидел подвисания картинки, в надежде что задержка чтения временная и вот-вот все нормализуется? Сменить блокирующее ожидание сокета на свой цикл проверки, чтобы был появился шанс проверить флаг?


Кё>В архитектуре изолированных процессов, producer получает сообщение от сокета о приеме данных, и добавляет в буфер, или получает сообщение от проигрывателя, и отдает частично заполненный. Расширение делается добавлением всего одного сообщения.


Если в архитектуре изолированных процессов producer выполняет блокирующие операции ввода-вывода, вы можете отсылать ему сообщения сколько угодно.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[12]: Многопоточность сегодня
От: сипласплас  
Дата: 11.10.07 12:16
Оценка:
Здравствуйте, GlebZ, Вы писали:

GZ>Здравствуйте, сипласплас, Вы писали:


С>>не забывай про необходимый memory barrier

GZ>А что memory barrier? Это всего лишь еще одна ссылка на тот же адрес. Даже если они будут различаться с хранящейся в OЗУ, после сборки выполнение продолжится, и будет присвоен корректный адрес. Атомарность не пострадает.

При чем здесь _сборка_? Я вот про что (как назло, где Wolfhound, где IT, где Vlad наконец? Неужели обязательно надо написать "с++ рулит!!!" что-бы они тут же подоспели?):


public class SharedResource{}

public class test
{
    SharedResource _shared = new SharedResource();
    Thread         _thread = null;

    void Start()
    {
          _thread = new Thread( new ThreadStartDelegate(this.ThreadProc) );
          Sleep(1000);
          _shared = null;
          Sleep(1000);
          _thread.Join();          
   }    

   private void ThreadProc()
   {
         //а тут мы вовсю юзаем _thread...
   }
}
Re[3]: Многопоточность сегодня
От: iZEN СССР  
Дата: 11.10.07 12:18
Оценка: :)))
Здравствуйте, eao197, Вы писали:

E>Remark писал не о том, насколько хорошо работает на многоядерных машинах ОС и насколько отшлифован в ней шедулер. А о том, как быть программисту, когда в его распоряжении оказывается несколько процессоров.


Ему надо было точно разграничить области: прикладная область программирования и системная область программирования. Иначе получился абстрактный призыв ко всем слоям населения, охваченным электрическими сетями.

E>Например. В случае одного ядра выгодно было выделять отдельные нити для выполнения операций ввода-вывода. Скажем на отдельной нити работает ACE_Reactor, который прослушивает N сокетов и активирует M ACE_Event_Handler-ов. Event_Handler-ы вычитывают данные из сокета, оформляют их в сообщения и ставят в очередь сообщений другой нити для обработки. А так же извлекают из своих очередей сообщений сообщения с исходящими данными в своих методах handle_output (когда Reactor обнаруживает готовность сокета к записи). На одном ядре схема работает отлично.


E>Но, на двух ядрах оказывается, что стоимость переключения контекста между нитью-обработчиком и нитью ACE_Reactor-а слишком высока, чтобы передавать входящий/исходящий трафик через очереди сообщений.


E>Вопрос в том, как перепроектировать подобное приложение на два/четыре/восемь ядер сейчас так, чтобы при появлении 80(!) ядер приложение не пришлось перепроектировать с нуля заново.


Я не знаю, что такое "ACE_Reactor" -- впервые слышу об этой идиоме программирования. И всё, что с ней связано, скорее всего, относится к практическому аспекту конкретной реализации какой-то сущности. Так что индуцировать на её основе принципы ДЛЯ_ВСЕХ не имеет смысла. Она может быть использована лишь как пример, но не эталон (не)применимости.
Re[4]: Многопоточность сегодня
От: LaptevVV Россия  
Дата: 11.10.07 12:21
Оценка:
Здравствуйте, Кодёнок, Вы писали:

Кё>Здравствуйте, LaptevVV, Вы писали:


Кё>>> Алгоритм для многих исполнителей — я о таком не слышал.

Кё>Там целый большой сайт Куда именно смотреть?
А там действительно много всего о параллельных алгоритмах.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[11]: Многопоточность сегодня
От: remark Россия http://www.1024cores.net/
Дата: 11.10.07 12:29
Оценка:
Здравствуйте, сипласплас, Вы писали:

С>>>Ты у себя в программе вот так спокойно делаешь с поинтерами, к которым идет доступ из разных тредов?


R>>На x86 да, а почему бы и нет? Это экстремально быстро.


С>remark, а memory barrier? Или это я один тут параноик?


Нет, я тоже параноик.
Но на x86 тут можно и нужно делать без барьеров.


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[13]: Многопоточность сегодня
От: remark Россия http://www.1024cores.net/
Дата: 11.10.07 12:34
Оценка:
Здравствуйте, сипласплас, Вы писали:

С>Здравствуйте, GlebZ, Вы писали:


GZ>>Здравствуйте, сипласплас, Вы писали:


С>>>не забывай про необходимый memory barrier

GZ>>А что memory barrier? Это всего лишь еще одна ссылка на тот же адрес. Даже если они будут различаться с хранящейся в OЗУ, после сборки выполнение продолжится, и будет присвоен корректный адрес. Атомарность не пострадает.

С>При чем здесь _сборка_? Я вот про что (как назло, где Wolfhound, где IT, где Vlad наконец? Неужели обязательно надо написать "с++ рулит!!!" что-бы они тут же подоспели?):


С>

С>public class SharedResource{}

С>public class test
С>{
С>    SharedResource _shared = new SharedResource();
С>    Thread         _thread = null;

С>    void Start()
С>    {
С>          _thread = new Thread( new ThreadStartDelegate(this.ThreadProc) );
С>          Sleep(1000);
С>          _shared = null;
С>          Sleep(1000);
С>          _thread.Join();          
С>   }    

С>   private void ThreadProc()
С>   {
С>         //а тут мы вовсю юзаем _thread...
С>   }
С>}

С>



После "захвата" _shared в ThreadProc() надо просто проверить на null. InterlockedXXX здесь не нужен.
И это надо сделать в люом случае в такой ситуации, даже если обращения к _shared защищено мьютексами.


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[4]: Многопоточность сегодня
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 11.10.07 12:36
Оценка:
Здравствуйте, iZEN, Вы писали:

E>>Remark писал не о том, насколько хорошо работает на многоядерных машинах ОС и насколько отшлифован в ней шедулер. А о том, как быть программисту, когда в его распоряжении оказывается несколько процессоров.


ZEN>Ему надо было точно разграничить области: прикладная область программирования и системная область программирования. Иначе получился абстрактный призыв ко всем слоям населения, охваченным электрическими сетями.


Я не помню, чтобы remark говорил что-нибудь о разработке ОС в условиях многоядерности.

Чтоже до деления на прикладное и системное программирование...
Вот, например, сервера БД и встраиваемые БД -- это системное или прикладное программирование?
А компиляторы?
А Web-сервера?

ZEN>Я не знаю, что такое "ACE_Reactor" -- впервые слышу об этой идиоме программирования. И всё, что с ней связано, скорее всего, относится к практическому аспекту конкретной реализации какой-то сущности. Так что индуцировать на её основе принципы ДЛЯ_ВСЕХ не имеет смысла. Она может быть использована лишь как пример, но не эталон (не)применимости.


Мне кажется, вам самому нужно определиться с тем, что вы хотели сказать. Судя по всему, многие читатели поняли, о чем говорил remark. Вы же насоветовали ему лучше ознакомиться с Solaris, LWP, TLS и пр. Хотя суть этого совета от меня ускользнула.

ACE_Reactor -- это C++ный фреймворк в составе библиотеки ACE. Он берет на себя задачу контроля за состоянием N дескрипторов каналов ввода/вывода (под Unix-ом это могут быть пайпы, сокеты, файлы, под Windows -- сокеты/пайпы). За каждый канал должен отвечать специальный объект-наследник ACE_Event_Handler. Т.е. ACE_Reactor работает в качестве мультиплексора (или демультиплексора -- путаюсь в этих терминах) событий.

В простейшем случае ACE_Reactor является оберткой над while{} c select-ом внутри. Когда канал переходит в состояние готовности к чтению, Reactor вызывает у соответствующего Event_Handler-а метод handle_input. Когда канал переходит в состояние готовности к записи -- вызывается метод handle_output. И т.д.

ACE_Reactor используется в качестве базового слоя при реализации различных реактивных (т.е. реагирующих на происходящие события) сетевых служб. А уже что это будут за службы -- служба синхронизации времени, Web-сервер, сервер БД, балансировщих нагрузки или еще что -- зависит от задачи.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[5]: Многопоточность сегодня
От: iZEN СССР  
Дата: 11.10.07 12:42
Оценка:
Здравствуйте, GlebZ, Вы писали:

R>>Меня лично на PIV3.0+1Гб не устраивает скорость компиляции,

GZ>У меня тормозит компиляция NET, только когда много сборок. Теже файлы но в одной сборке компилируются мухой. Соответсвенно вывод что проблема в диск+скорость кэша(то бишь доступа к озу).
GZ>Что касается С++, то там те же проблемы. Дополнительный проц не сильно увеличит скорость компиляции.

Вы сами проверяли?
А я проверял. Двухъядерный процессор рвёт одноядерный на одной и той же частоте (Athlon64 X2 2ГГц vs. AthlonXP 1,8ГГц) в компиляции исходников C/C++ компилятором GCC более чем в 2,5 раза (двадцать пять минут против полутора часов) -- масштабируемость фактически линейная при одинаковой латентности подсистмы памяти и кэша L2).

R>>не устраивает скорость работы навороченных GUI типа Open Office/MS Visual Studio,

GZ>Основные проблемы память+диск.
R>>не устраивает скорость запуска очень многих программ.
GZ>Основные проблемы память+диск.
Для этого придумали различные QuickStart'ы. Для OpenOffice есть. Недавно анонсирован и для последней версии JRE:
http://www.linux.org.ru/jump-message.jsp?msgid=2192306

Но всё это костыли. Если всё рабочее окружение отправить в своп, а при загрузке компьютера оотуда всё доставать в оперативку... Но можно использовать энергонезависимое ОЗУ большой ёмкости (несколько гигабайт) и отказаться от винчестера вообще, тогда все установленые приложения и система фактически имеют включенную готовность, как радиоприёмник.
Re[5]: Многопоточность сегодня
От: Andrei F.  
Дата: 11.10.07 12:44
Оценка:
Здравствуйте, сипласплас, Вы писали:

С>по моим сведениям присванивание ссылки в c# — атомарно. Кроме того, нужно делать memory barrier. А он делается с пом. InterlockedXXX — синхронизация кешей


Твои сведения сильно ошибочные. Если ты сохранишь значение ссылки в переменной, которая видна потоку на другом ядре и не сделаешь в явном виде барьер памяти — это будет очень большой ошибкой.
Ты хотя бы представляешь себе потери в производительности, если каждое присваивание ссылки будет сделано через InterlockedExchange, который является full fence?
Re[6]: Многопоточность сегодня
От: сипласплас  
Дата: 11.10.07 13:02
Оценка:
Здравствуйте, iZEN, Вы писали:

ZEN>Здравствуйте, GlebZ, Вы писали:


R>>>Меня лично на PIV3.0+1Гб не устраивает скорость компиляции,

GZ>>У меня тормозит компиляция NET, только когда много сборок. Теже файлы но в одной сборке компилируются мухой. Соответсвенно вывод что проблема в диск+скорость кэша(то бишь доступа к озу).
GZ>>Что касается С++, то там те же проблемы. Дополнительный проц не сильно увеличит скорость компиляции.

ZEN>Вы сами проверяли?

ZEN>А я проверял. Двухъядерный процессор рвёт одноядерный на одной и той же частоте (Athlon64 X2 2ГГц vs. AthlonXP 1,8ГГц) в компиляции исходников C/C++ компилятором GCC более чем в 2,5 раза (двадцать пять минут против полутора часов) -- масштабируемость фактически линейная при одинаковой латентности подсистмы памяти и кэша L2).

Дак и VS2005 это _умеет_. Вам неочевидно почему этого не умеет VS2003? Не из-за винды же...

[]
Re[6]: Многопоточность сегодня
От: сипласплас  
Дата: 11.10.07 13:06
Оценка:
Здравствуйте, Andrei F., Вы писали:

AF>Здравствуйте, сипласплас, Вы писали:


С>>по моим сведениям присванивание ссылки в c# — атомарно. Кроме того, нужно делать memory barrier. А он делается с пом. InterlockedXXX — синхронизация кешей


AF>Твои сведения сильно ошибочные.


Ошибочные в том, что при любое присваивание ссылки ведет к full fence?

AF>Если ты сохранишь значение ссылки в переменной, которая видна потоку на другом ядре и не сделаешь в явном виде барьер памяти — это будет очень большой ошибкой.


Спасибо

AF>Ты хотя бы представляешь себе потери в производительности, если каждое присваивание ссылки будет сделано через InterlockedExchange, который является full fence?


Вау! Какой слог!
Re[14]: Многопоточность сегодня
От: сипласплас  
Дата: 11.10.07 13:07
Оценка:
Здравствуйте, remark, Вы писали:

R>Здравствуйте, сипласплас, Вы писали:


[]

R>После "захвата" _shared в ThreadProc() надо просто проверить на null. InterlockedXXX здесь не нужен.

R>И это надо сделать в люом случае в такой ситуации, даже если обращения к _shared защищено мьютексами.

А если заменить _shared = null на _shared = new SharedResource()? Ты понял о чем я?

R>
Re[12]: Многопоточность сегодня
От: сипласплас  
Дата: 11.10.07 13:09
Оценка:
Здравствуйте, remark, Вы писали:

R>Здравствуйте, сипласплас, Вы писали:


С>>>>Ты у себя в программе вот так спокойно делаешь с поинтерами, к которым идет доступ из разных тредов?


R>>>На x86 да, а почему бы и нет? Это экстремально быстро.


С>>remark, а memory barrier? Или это я один тут параноик?


R>Нет, я тоже параноик.

R>Но на x86 тут можно и нужно делать без барьеров.

Почему?!

R>
Re[5]: Многопоточность сегодня
От: iZEN СССР  
Дата: 11.10.07 13:17
Оценка: :)
Здравствуйте, eao197, Вы писали:

E>>>Remark писал не о том, насколько хорошо работает на многоядерных машинах ОС и насколько отшлифован в ней шедулер. А о том, как быть программисту, когда в его распоряжении оказывается несколько процессоров.


iZEN>>Ему надо было точно разграничить области: прикладная область программирования и системная область программирования. Иначе получился абстрактный призыв ко всем слоям населения, охваченным электрическими сетями.


E>Я не помню, чтобы remark говорил что-нибудь о разработке ОС в условиях многоядерности.


E>Чтоже до деления на прикладное и системное программирование...

E>Вот, например, сервера БД и встраиваемые БД -- это системное или прикладное программирование?

Это прикладное программирование.

E>А компиляторы?


Прикладное.

E>А Web-сервера?


Прикладное.

Что системное программирование: то, что работает в режиме ядра -- это прежде всего драйверы и шедулер аппаратных потоков исполнения.

iZEN>>Я не знаю, что такое "ACE_Reactor" -- впервые слышу об этой идиоме программирования. И всё, что с ней связано, скорее всего, относится к практическому аспекту конкретной реализации какой-то сущности. Так что индуцировать на её основе принципы ДЛЯ_ВСЕХ не имеет смысла. Она может быть использована лишь как пример, но не эталон (не)применимости.


E>Мне кажется, вам самому нужно определиться с тем, что вы хотели сказать. Судя по всему, многие читатели поняли, о чем говорил remark. Вы же насоветовали ему лучше ознакомиться с Solaris, LWP, TLS и пр. Хотя суть этого совета от меня ускользнула.


Да только что нашёл в Google, что такое ACE. Примочка на C++ для решения вдруг возникших проблем с управлением нагрузкой многоядерных процессоров.

E>ACE_Reactor -- это C++ный фреймворк в составе библиотеки ACE. Он берет на себя задачу контроля за состоянием N дескрипторов каналов ввода/вывода (под Unix-ом это могут быть пайпы, сокеты, файлы, под Windows -- сокеты/пайпы). За каждый канал должен отвечать специальный объект-наследник ACE_Event_Handler. Т.е. ACE_Reactor работает в качестве мультиплексора (или демультиплексора -- путаюсь в этих терминах) событий.


E>В простейшем случае ACE_Reactor является оберткой над while{} c select-ом внутри. Когда канал переходит в состояние готовности к чтению, Reactor вызывает у соответствующего Event_Handler-а метод handle_input. Когда канал переходит в состояние готовности к записи -- вызывается метод handle_output. И т.д.


E>ACE_Reactor используется в качестве базового слоя при реализации различных реактивных (т.е. реагирующих на происходящие события) сетевых служб. А уже что это будут за службы -- служба синхронизации времени, Web-сервер, сервер БД, балансировщих нагрузки или еще что -- зависит от задачи.



На его основе что-либо системное сделали (работающее в ядре ОС) или делают только приложения, так как на основе Pthreads и LWP? (Инетресуюсь, потому что хочу провести/или не провести черту применимости ACE между системным и прикладным использованием)
Re[5]: Многопоточность сегодня
От: Sergey Россия  
Дата: 11.10.07 13:18
Оценка:
> Что касается С++, то там те же проблемы. Дополнительный проц не сильно увеличит скорость компиляции.

Здрасте-приехали. А че у меня тогда инкредибилд пересобирает солюшен за 20-30 минут, в то время как локальная пересборка — более 2 часов?
Posted via RSDN NNTP Server 2.1 beta
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[10]: Многопоточность сегодня
От: Andrei F.  
Дата: 11.10.07 13:22
Оценка:
Здравствуйте, remark, Вы писали:

R>>>А если разрешено, то тут не надо никаких InterlockedXXX, просто присвоить/считать значение указателя.


С>>Ты у себя в программе вот так спокойно делаешь с поинтерами, к которым идет доступ из разных тредов?


R>На x86 да, а почему бы и нет? Это экстремально быстро.


Тут будет возможна ситуация, когда на другом ядре обновленное значение указателя уже будет в кэше, а сами данные, на которые он указывает — нет. Поэтому на многоядерной системе так делать нельзя. На одноядерной можно, но тоже есть ограничение — переменная с указателем должна быть правильно выровнена.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.