суббота, ноября 02, 2013

Что сказал Рихтер

Давно обещала рассказать о лекции Рихтера про потоки. Такие лекции - это не что-то редкое и удивительное, Рихтер - совладелец компании Wintellect и они за деньги прочтут эту лекцию всем желающим. Если у вас есть возможность на его занятия прийти - очень рекомендую.
Ценны они в первую очередь возможностью задать Рихтеру вопросы и интересными примерами кода, однако были высказаны несколько полезных мыслей. Итак, Рихтер рекомендует. (Никаких откровений, впрочем)
Не надо плодить потоки, потому что переключение контекстов - вещь дорогая. Разумно делать столько потоков, сколько в машине есть ядер.
Если уж поток создали, постарайтесь его не блокировать без крайней необходимости. Речь идет не только о мьютексах, но и о Join, Sleep.
 
Не надо играть с thread pool. "Leave the thread pool alone".

Ну а также volatile в C# и в C++ разные. В C# volatile "cannot cache and fence", а в C++ только "cannot cache".

22 коммент.:

Unknown комментирует...

> Не надо играть со thread pool. "Leave the thread pool along".

Что подразумевается под этим предложением?

Brainstream комментирует...

Так он же всё это писал в CLR via C#.

Alena комментирует...

Maxim Dobryakov

> Не надо играть со thread pool. "Leave the thread pool along".

Что подразумевается под этим предложением?


Вот это не трогать.

OmariO комментирует...

Есть маленькая деталь - с Visual C++ 2005 volatile точно соответствует volatile'у C#, т.е. ограничивает возможный реордеринг.

OmariO комментирует...

Вот посмотрел сейчас для VS 2012 - они добавили опцию совместимости с ISO.

Анонимный комментирует...

Может тогда "Leave the thread pool alone"?

Мысли, конечно, полезные, но, довольно банальные.

Alena комментирует...

Анонимный

Может тогда "Leave the thread pool alone"?

именно, спасибо, поправила

4ybaka комментирует...

Был как раз в октябре на 2х тренингах у Рихтера: .Net в целом и multithreading. По .Net'у особых откровений не было, но было много интересных нюансов по внутренностям. Так сказать из первых рук.
А вот тренинг по многопоточности был из разряда "Вау!". И мне кажется, что не прослушав этот курс, люди не полностью осознают всех этих "банальностей". Если бы это действительно были банальности, то у меня бы сейчас не было в трее сервиса для управления bluetooth'ом создавшего под себя 74 потока...
Мы когда на работе рассказывали о своих впечатлениях по тренингу, нас тоже не понимали. Потом провели небольшой митинг, где более подробно рассказали про все это дело, с примерами (а их, к сожалению, очень много), и народ похоже проникся:)
Так что если будет возможность, то на тренинг по многопоточности ехать обязательно. Если повезет, может получится поужинать с Рихтером;)

Unknown комментирует...

Если треды много вводят-выводят, то их можно открыть и больше 4 (считаем, что процессор 4-ядерный).

Если лимитирует доступ к памяти, то часто и 2 треда бесполезны. Я когда открыл 2 независимых процесса RandomForest на большом наборе данных (50К*80), фокус не удался: каждый считал ровно вдвое медленнее, чем если бы он был один. Хотя показывалась загрузка процессора 200%.

4ybaka комментирует...

Если треды много вводят-выводят, то их можно открыть и больше 4 (считаем, что процессор 4-ядерный).
Об этом и речь. Если треды много вводят-выводят, то Вам свои треды вообще не нужны. Пользуйтесь асинхронным апи, и как io операция будет готова, пул сам выделит для Вас тред. Может быть Вам вообще хватает 1 потока.
На мой взгляд посыл Рихтера был не в том, что переключение контескта дорогая вещь, а в том, что если вам нечем занять поток на 100% времени, то отдельный поток вам не нужен.

Unknown комментирует...

Речь идёт о С++ под Линуксом, и вот что написано в мэне.

"The current Linux POSIX AIO implementation is provided in userspace by glibc. This has a number of limitations, most notably that maintaining multiple threads to perform I/O operations is expensive and scales poorly."

Так что я уж лучше сам открою свои треды.

const.me комментирует...

http://channel9.msdn.com/Shows/AppFabric-tv/AppFabrictv-Threading-with-Jeff-Richter
или
http://www.youtube.com/watch?v=KzDShvKbEMs
?

4ybaka комментирует...

Речь идёт о С++ под Линуксом, и вот что написано в мэне.
Ну это многое меняет. Рихтер рассуждает все относительно Windows, и это не означает, что те же советы будут хорошо работать под другими ОС.

Анонимный комментирует...

Я лекцию, конечно, не слышал, но некоторый опыт и с многопоточностью, и с асинхронным IO имею, и у меня откровения такого рода вызывают сомнения. Что это значит - "не играть"? Это просто паттерн организации, инструмент.

Переключение контекстов дорогое - ну надо же, никто и не знал. А многопроцессность - не дорого? Все срочно назад в будущее, в MS-DOS.

Анонимный комментирует...

4убака:

"если вам нечем занять поток на 100% времени, то отдельный поток вам не нужен."

...а если вам есть чем занять поток на 100% времени, то у вас недостаточно мощный для вашей задачи процессор. Вообще, суть многопроцессности в том, что каждый поток исполнения (нитка или процесс, неважно) не заняты 100% времени.

Анонимный комментирует...

Скиньте ссылку на годное чтиво о реальных многопоточных задачах, которые требуют реальных решений, а не просто отделение gui от расчетов и обращений к базе данных. Скиньте пожалуйста полную фамилию этого крутого чувака Рихтера и ссылку на него в интернете.

Анонимный комментирует...
Этот комментарий был удален администратором блога.
Артем Ерофеев комментирует...

Алёна, а что за тренинг?

Alena комментирует...

...so why?
Алёна, а что за тренинг?

.NET threading in C#

Анонимный комментирует...

Welcome back!

Сергей комментирует...

> Вот это не трогать.

Что значит не трогать? Не давать задачи на выполнение, не использовать Task<>?
Где-то есть более развернутое объяснение этой идеи?

> В C# volatile "cannot cache and fence"

Согласно www.albahari.com:

The volatile keyword instructs the compiler to generate an acquire-fence on every read from that field, and a release-fence on every write to that field. ... These “half-fences” are faster than full fences because they give the runtime and hardware more scope for optimization.
...
Notice that applying volatile doesn’t prevent a write followed by a read from being swapped, and this can create brainteasers.

И там ниже еще есть пример.

Alena комментирует...

Сергей
Что значит не трогать?

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

Где-то есть более развернутое объяснение этой идеи?

В лекциях Рихтера.

И там ниже еще есть пример.

В C# volatile "cannot cache and fence" = В C# volatile означает запрет на кэширование и обеспечивает барьер.