Многопоточность сегодня
От: remark Россия http://www.1024cores.net/
Дата: 10.10.07 11:28
Оценка: 568 (66)
Уже достаточно давно программисты экстенсивно применяют многопоточность при реализации систем. При этом многопоточность применялась в основном для таких вещей как упрощение модели программирования, маскирование латентности блокирующих операций и т.д. И так же это всё происходило в подавляющем большинстве в контексте одного ядра/процессора. Соотв. распространены следующие принципы и подходы:
— Можно завести любое кол-во потоков. Иимеется в виду любое в пределах сотни. Т.е. кол-во потоков определяется исключительно потребностью архитектуры, но не аппаратной платформой.
— Можно произвольным образом распределить работу по потокам. Т.к. всё равно всё выполняется на одном ядре, то это не имеет значения.
— Можно и нужно экстенсивно применять мьютексы для синхронизации. Т.к. всё выполняется на одном ядре, то это практически не влияет на производительность и масштабируемость.
— Можно произвольным образом разделять данные между потоками. Т.к. процессор один, то это никак не влияет на производительность и масштабируемость. Фактически система работает так, как будто поток один, просто он выполяет то одну функцию, то другую.

Всё это я называю «многопоточность на одном ядре». Фактически система, построенная по таким принципам, образно является «однопоточной с кооперативной многозадачностью».

И всё это становится кардинально не верным с появлением массовых многоядерных процессоров. Во второй половине следующего года Intel намерена выпустить процессор с 16 аппаратными потоками: здесь
Автор: remark
Дата: 20.09.07

И через 5 лет они собираются выпустить процессор с 80 ядрами! (Представть свои программы на 80 ядрах! Есть идеи как их использовать?)

Что бы эффективно использовать новые аппаратные платформы, нужны совершенно новые принипы и подходы. Нужна «многопоточность на множестве ядер». Под эффективностью я подразумеваю, что бы программа на 8 ядрах выполнялась хотя бы не медленнее, чем на одном. Шутка шуткой, а на форумах посвящённым многопоточности сейчас один из самых распространённых вопросов «Почему моя программа, которая делает Х, на 4-ёх ядерной машине работает медленнее, чем на 1-ядерной?»

Потому что старые принципы многопоточности патологически не работают в новом контексте! Я уверен, что значительная часть многопоточных систем «старой школы» будут быстрее работать на многоядерном процессоре, если банально привязать все потоки программы к одному ядру! Т.к. синхронизация всё равно убивает потенциальный параллелизм, а разделение данных вносит коллосальные пенальти.
Некоторое время назад я был свидетелем следующей ситуации. Серверное ПО запустили на двух-процессорной машине (в надежде, что оно будет работать в 2 раза быстрее. ха-ха). Оно стало работать в 10 (!) раз медленнее (как потом оказалось причиной было постоянное разделение модифицируемых данных между двумя потоками).

Сейчас наиболее общий рецепт выглядит примерно следующим образом:
— Создать кол-во потоков по кол-ву аппаратных потоков. Как следствие — кол-во потоков не должно быть «зашито» в программу, т.к. она может выполняться на разных платформах. И как второе следствие – управление кол-вом потоков не должно быть заботой прикладного программиста (ну по крайней мере того же программиста, но когда он играет роль прикладного ).
— Работа должна быть распределена по потокам [примерно] равномерно. Соотв. это тоже не получится зашивать в программу и поручать прикладному программисту, т.к. кол-во потоков и кол-во и содержание работы меняться.
— Нельзя экстенсивно применять мьютесы/синхронизацию/блокировки. Т.к. это фактически заставит систему сериализоваться и выполняться «на одном ядре». Ни о какой масштабируемости тут не может быть и речи.
— По возможности надо элиминировать разделяемые данные. Совместная работа над одними модифицируемыми данными сейчас работает ооочень медленно и становится одним из важнейших новых боттлнеков аппаратной платформы, на ряду с тактами ядра, шиной к памяти, диском, сетью. И никаких изменений в лучшую сторону тут не предвидится. Только в худшую. (Это не относится к константным данным, их можно и нужно разделять между потоками)

Если выразить это более кратко: *каждое* ядро должно быть обеспечено *своей* работой и *своими* данными, и работать над ними *независимо*.
К сожалению пока никто не придумал как приготовить этот рецепт в общем виде... Т.е. что бы программист был занят только прикладными задачами, а всё остальное происходило как-то само собой.

Естественно могут иметь место и частные случаи. Например, приложение по обработке изображений или CAD/CAM/CAE/CASE. Тут скорее всего имеет смысл эффективно распараллеливать только одну основную функцию, например, обработку изображения, или рассчёт параметров модели (все остальные функции — графический интерфейс, фоновые задачи — по прежнему могут быть реализованы по старым принципам). Тут сейчас ситуация обстоит немного лучше. Тут (и только тут) на помощь могут придти такие средства как OpenMP, RapidMind, Intel TBB, Java Fork/Join и тд.:
www.openmp.org
www.rapidmind.com
osstbb.intel.com
gee.cs.oswego.edu/dl/papers/fj.pdf
К сожалению все эти средства подходят для очень ограниченного круга задач, и не подходят для реализации более общих и не типовых задач. И всё равно они не снимают с программиста основной задачи — что конкретно и как конкретно должно быть распараллелено. Это по прежнему должен решать программист, и он по прежнему должен обеспечить достаточное кол-во потенциального параллелизма, возможность для независимой работы потоков без разделяемых данных и т.д.

Есть ещё 2 вещи стоящие упоминания в данном контексте: готовые высокооптимизированные библиотеки и автоматическое распараллеливание кода.

Для решения типовых задач имеется ряд высокооптимизированных библиотек. Например можно посмотреть на:
Intel Integrated Performance Primitives (IPP):
http://www.intel.com/cd/software/products/asmo-na/eng/219767.htm
И AMD Performance Library (APL):
http://developer.amd.com/apl.jsp
Задачи, которые они могут решать включают:
— обработка/кодирование/декодирование видео
— обработка/кодирование/декодирование изображений
— обработка/кодирование/декодирование аудио
— операции над матрицами/векторами/строками
и т.д.
Понятно, что на общее решение такие библиотеки не тянут. Однако, если решаемая задача укладывается в возможности библиотеки, то имеет большой смысл применять такую библиотеку (Intel — платная, AMD — бесплатная).

Автоматическое распараллеливание кода.
Здесь не на что смотреть! Проходите, не задерживаетесь!
Сейчас автоматические распараллеливатели могут очень мало и очень конкретного. И вам всё равно придётся убеждаться, что распараллелилось то, что надо, так, как надо, и оно не ломается при последующих модификациях кода (напоминает борьбу с оптимизатором БД ). Фактически правильнее считать, что автоматического распараллеливания кода *нет*. Сейчас и в ближайшую декаду. Если кто-то утверждает обратное, то он либо не разбирается в вопросе, либо хочет вам что-то продать
За подробностями смотрите интервью с Джеем Хоефлингером, который занимается автоматическим распараллеливанием с середины 80:
http://www.thinkingparallel.com/2007/08/14/an-interview-with-dr-jay-hoeflinger-about-automatic-parallelization/


Подытожу. Мы сейчас находимся на перегибе развития. Что бы поспеть за развитием, а не попасть в кювет, надо многое переосмыслить и смотреть на вещи по новому. Новые принципы и подходы только формируются, ни у кого пока нет *универсальных* решений. Всё, что сейчас выдают за таковые, за универсальные решения для многоядерности (OpenMP, RapidMind, Intel TBB) — маркетинг. Ну, возможно, это лишь строительные блоки, но ни как не решение. Сейчас всё зависит исключительно от компетентности конкретного программиста, разрабатывающего конкретную систему.


Дополнительные ссылки для интересующихся:

Фундаментальная работа на тему, почему процессоры *не* будут становится всё быстрее и быстрее, и что делать теперь:
The Landscape of Parallel Computing Research: A View from Berkeley

Если кто ещё не читал — популярные заметки Герба Саттера:
The Free Lunch Is Over
The Pillars of Concurrency
How Much Scalability Do You Have or Need?

OpenMP Does Not Scale — Or Does It?. В очень забавной форме показываются проблемы, связанные с написанием параллельных программ.

How-to Split a Problem into Tasks. Как выявлять параллелизм в системе (подходит в основном для HPC).

Ещё интересные заметки Michael Suess:
Is the Multi-Core Revolution a Hype?
Moore’s Law is Dead — Long Live Moore’s Law!
How Much of the Industry Will Go Parallel?
Parallel Programming is Entering the Mainstream — or isn’t it?



1024cores — all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re: Многопоточность сегодня
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 10.10.07 12:15
Оценка: 12 (2)
Здравствуйте, remark, Вы писали:

<...внимательно прочитано и поскипано...>

Так может пора возвращаться в Unix-way? Множество однопоточных программ, общающихся между собой по IPC?


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[2]: Многопоточность сегодня
От: remark Россия http://www.1024cores.net/
Дата: 10.10.07 12:42
Оценка:
Здравствуйте, eao197, Вы писали:

E>Так может пора возвращаться в Unix-way? Множество однопоточных программ, общающихся между собой по IPC?



Это ничего не меняет. Такой дизайн можно тривиально переделать под использование потоков, и при этом использовать более дешёвые методы взаимодействия без лишних копирований данных, совместно использовать константные (или read-mostly) данные, упростить администрирование/настройку.
А если множество процессов будет общаться через shared memory, так вообще получаем то же самое многопоточное приложение с точностью до констант.
По большому счёту тут не принципиально, что использовать потоки или процессы (с разделяемой памятью). Все те же сложные вопросы остаются — как распределить работу между потоками/процессами, как разделять данные и как синхронизировать потоки/процессы, как организовать передачу данных/сообщений между потоками/процессами, как делать балансировку нагрузки между потоками/процессами.


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re: Многопоточность сегодня
От: GlebZ Россия  
Дата: 10.10.07 12:45
Оценка: 19 (2) +1 -1
Здравствуйте, remark, Вы писали:

R>Всё это я называю «многопоточность на одном ядре». Фактически система, построенная по таким принципам, образно является «однопоточной с кооперативной многозадачностью».

Мне больше нравится термин "квазимногопоточность". Кооперативная многозадачность — все таки просто термин невытесняющей многозадачности.

R>И через 5 лет они собираются выпустить процессор с 80 ядрами! (Представть свои программы на 80 ядрах! Есть идеи как их использовать?)

Хороший вопрос. Я задумался, а нужно ли иметь на десктопе более чем два ядра по 3 гГц. Может в своем развитии десктопы дошли до точки когда дальнейшее увеличение производительности уже не даст видимого эффекта для пользователя?
(дома стоит PIV2.4, на работе DUAL 3.0, кардинальной разницы в работе не вижу.)
Re: Библиотеки
От: remark Россия http://www.1024cores.net/
Дата: 10.10.07 12:49
Оценка: 1 (1)
Здравствуйте, remark, Вы писали:

R>Для решения типовых задач имеется ряд высокооптимизированных библиотек. Например можно посмотреть на:

R>Intel Integrated Performance Primitives (IPP):
R>http://www.intel.com/cd/software/products/asmo-na/eng/219767.htm
R>И AMD Performance Library (APL):
R>http://developer.amd.com/apl.jsp
R>Задачи, которые они могут решать включают:
R> — обработка/кодирование/декодирование видео
R> — обработка/кодирование/декодирование изображений
R> — обработка/кодирование/декодирование аудио
R>- операции над матрицами/векторами/строками
R>и т.д.
R>Понятно, что на общее решение такие библиотеки не тянут. Однако, если решаемая задача укладывается в возможности библиотеки, то имеет большой смысл применять такую библиотеку (Intel — платная, AMD — бесплатная).


С одной стороны библиотеки являются самым простым и автоматическим решением. Они не требую практически никакого приложения умственных усилий. Однако применение их в коммерческих продуктах для решения основных задач чревато, т.к. они имеют очень жёсткую "семантическую стену". Допустим разработано ПО жёстко зашитое на использование такой библиотеки. ПО выпущено быстро и качественно. Но теперь встаёт задача сделать "немного другую" обработку нежели предусматривает библиотека. Ууупс. Можно, конечно, купить премиум лицензию, подать фича-реквест и ждать...
Опен-сорц библиотеки в таком свете выглядят, конечно, более привликательно. Всегда можно подправить то, что необходимо... Ни та, ни другая *не* опен-сорц...



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

R>>И через 5 лет они собираются выпустить процессор с 80 ядрами! (Представть свои программы на 80 ядрах! Есть идеи как их использовать?)

GZ>Хороший вопрос. Я задумался, а нужно ли иметь на десктопе более чем два ядра по 3 гГц. Может в своем развитии десктопы дошли до точки когда дальнейшее увеличение производительности уже не даст видимого эффекта для пользователя?
GZ>(дома стоит PIV2.4, на работе DUAL 3.0, кардинальной разницы в работе не вижу.)

Так думали при появлении процессора 1 МГц.
Так думали при появлении процессора 10 МГц.
Так думали при появлении процессора 100 МГц.
Так думали при появлении процессора 500 МГц.
Так думали при появлении процессора 1 ГГц.
Так думали при появлении процессора 2 ГГц.
Так думали при появлении процессора 3 ГГц.
Так думают при появлении 4-ёх ядерного процессора 3 ГГц.

Если бы произошёл всемирный и вечный фича-фриз у производителей софта, то да, достаточно было бы выпустить ещё одно поколение процессоров и всё, его бы хватило бы на всегда.

Но проблема, в том, что задачи, которые ставятся перед софтом постоянно растут с той же скоростью, с которой растёт производительность, даже быстрее. И конца этому не видно.
Над чем сейчас работают — распознование голоса/видео на лету.
О играх и серном ПО и говорить нечего.



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re: Арифметика
От: remark Россия http://www.1024cores.net/
Дата: 10.10.07 13:20
Оценка: +2 :))) :)
Здравствуйте, remark, Вы писали:

R>И всё это становится кардинально не верным с появлением массовых многоядерных процессоров. Во второй половине следующего года Intel намерена выпустить процессор с 16 аппаратными потоками: здесь
Автор: remark
Дата: 20.09.07

R>И через 5 лет они собираются выпустить процессор с 80 ядрами! (Представть свои программы на 80 ядрах! Есть идеи как их использовать?)


Позавчера однопоточная программа на одноядерном процессоре использовала 100% аппаратных ресурсов. Хорошо.
Вчера однопоточная программа на двухядерном процессоре использовала 50% аппаратных ресурсов. Допустим.
Сегодня однопоточная программа на четырёхядерном процессоре использует 25% аппаратных ресурсов. Хммм.
Завтра однопоточная программа на шестнадцатиядерном процессоре будет использовать 6.25% аппаратных ресурсов.
Послезавтра однопоточная программа на восьмидестиядерном процессоре будет использовать 1.25% аппаратных ресурсов.


Арифметика очень простая. Хотите быть автором программы, которая работает только на 1.25% от возможного?



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

R>>>И через 5 лет они собираются выпустить процессор с 80 ядрами! (Представть свои программы на 80 ядрах! Есть идеи как их использовать?)

GZ>>Хороший вопрос. Я задумался, а нужно ли иметь на десктопе более чем два ядра по 3 гГц. Может в своем развитии десктопы дошли до точки когда дальнейшее увеличение производительности уже не даст видимого эффекта для пользователя?
GZ>>(дома стоит PIV2.4, на работе DUAL 3.0, кардинальной разницы в работе не вижу.)

Меня лично на PIV3.0+1Гб не устраивает скорость компиляции, не устраивает скорость работы навороченных GUI типа Open Office/MS Visual Studio, не устраивает скорость запуска очень многих программ.



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

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


E>>Так может пора возвращаться в Unix-way? Множество однопоточных программ, общающихся между собой по IPC?



R>Это ничего не меняет. Такой дизайн можно тривиально переделать под использование потоков, и при этом использовать более дешёвые методы взаимодействия без лишних копирований данных, совместно использовать константные (или read-mostly) данные, упростить администрирование/настройку.

R>А если множество процессов будет общаться через shared memory, так вообще получаем то же самое многопоточное приложение с точностью до констант.

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

Однопоточность же для программы, по сравнению с многопоточностью, дает несколько преимуществ:
* простота (отсутствие гонок и тупиков в коде);
* скорость (отсутствие синхронизаций (даже в недрах стандартной библиотеки) и связанных с этим накладных расходов).

R>По большому счёту тут не принципиально, что использовать потоки или процессы (с разделяемой памятью). Все те же сложные вопросы остаются — как распределить работу между потоками/процессами, как разделять данные и как синхронизировать потоки/процессы, как организовать передачу данных/сообщений между потоками/процессами, как делать балансировку нагрузки между потоками/процессами.


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


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[4]: Многопоточность сегодня
От: remark Россия http://www.1024cores.net/
Дата: 10.10.07 16:01
Оценка: :)
Здравствуйте, eao197, Вы писали:

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


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


E>>>Так может пора возвращаться в Unix-way? Множество однопоточных программ, общающихся между собой по IPC?



R>>Это ничего не меняет. Такой дизайн можно тривиально переделать под использование потоков, и при этом использовать более дешёвые методы взаимодействия без лишних копирований данных, совместно использовать константные (или read-mostly) данные, упростить администрирование/настройку.

R>>А если множество процессов будет общаться через shared memory, так вообще получаем то же самое многопоточное приложение с точностью до констант.

E>С другой стороны, разделение приложения на однопоточные процессы может быть похоже на противостояние обмена сообщениями удаленному вызову подпрограмм. Обмен сообщениями заставляет разработчика проектировать места межпроцессового (межагентного) взаимодействия.


E>Однопоточность же для программы, по сравнению с многопоточностью, дает несколько преимуществ:

E>* простота (отсутствие гонок и тупиков в коде);
E>* скорость (отсутствие синхронизаций (даже в недрах стандартной библиотеки) и связанных с этим накладных расходов).

R>>По большому счёту тут не принципиально, что использовать потоки или процессы (с разделяемой памятью). Все те же сложные вопросы остаются — как распределить работу между потоками/процессами, как разделять данные и как синхронизировать потоки/процессы, как организовать передачу данных/сообщений между потоками/процессами, как делать балансировку нагрузки между потоками/процессами.


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



Такой момент есть. Но я бы назвал это организационным моментом, а не техническим. При написании многопоточного приложения ты не обязан заниматься половыми связями с разделяемыми структурами и мьютексами... хотя всегда очень тянет
Продумать структуру системы и структуру взимодействия можно всегда. Если делать многопоточное приложение на основе обмена сообщениями, то получается аналогично процессам — отсутствие гонок, чётко гранулированное и определенное взаимодействие и т.д. Ну в прочем не тебе это говорить.
Зато при использовании процессов ты гарантированно:
— Имеешь очень дорогое взаимодействие. Это скорее всего будет 2 системных вызова, 2 полных копирования данных, плюс ещё синхронизация и ещё куча непонятно чего. Более-менее не так ужасно тормозно это может быть только с IO-Lite:
http://www.usenix.org/publications/library/proceedings/osdi99/full_papers/pai/pai.pdf
Хотя его видимо никто не использует.
В случае же потоков это может действительно очень-очень-очень быстро. Порядка нескольких тактов.
— Имеешь копии read-mostly данных в памяти и каждого процесса. И в кэше.
— Имеешь сложность запуска/остановки/настройки приложения.

Единственное, что будет быстрее в случае процессов — это однопоточный рантайм в каждом процессе. Но это из-за тупого реплицирования всех данных. Я думаю, что основная проблема тут это — аллокация памяти. Но я надеюсь, что ты не используешь стандартный аллокатор памяти из crt в многопоточных программах?


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re: Многопоточность сегодня
От: Andrei F.  
Дата: 10.10.07 16:08
Оценка: 1 (1)
Здравствуйте, remark, Вы писали:

А какие сейчас есть средства для синхронизации работы ядер? Можно ли например передавать данные между ядрами, не затрагивая при этом основную память? А то если диспетчеру придется постоянно делать полную синхронизацию всех кэшей, то это на корню убьет преимущества от распараллеливания, когда фрагменты задачи невелики по времени выполнения....
Re[3]: Многопоточность сегодня
От: AVM Россия  
Дата: 10.10.07 18:11
Оценка: :)))
Здравствуйте, remark, Вы писали:

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


E>>Так может пора возвращаться в Unix-way? Множество однопоточных программ, общающихся между собой по IPC?



R>Это ничего не меняет. Такой дизайн можно тривиально переделать под использование потоков, и при этом использовать более дешёвые методы взаимодействия без лишних копирований данных, совместно использовать константные (или read-mostly) данные, упростить администрирование/настройку.

R>А если множество процессов будет общаться через shared memory, так вообще получаем то же самое многопоточное приложение с точностью до констант.
R>По большому счёту тут не принципиально, что использовать потоки или процессы (с разделяемой памятью). Все те же сложные вопросы остаются — как распределить работу между потоками/процессами, как разделять данные и как синхронизировать потоки/процессы, как организовать передачу данных/сообщений между потоками/процессами, как делать балансировку нагрузки между потоками/процессами.
IMHO самое основное, что мешает жить и что является первичной проблемой — как разделять данные.

Когда еще был студентом мой знакомый работал в одном НИИ который занимался разработкой многопроцессорных систем и знакомому (а он потом подключил меня к этой работе) предложили принять участие в разработке транслятора для многопроцессорных систем.
Основная идея которую туда пытались заложить — при написании кода можно было указать, может ли этот кусок код выполняться параллельно (если да — при каких условиях) и что является событием для запуска этого куска на выполнение.

Основной проблемой было как грамотно организовать распределение данных между потоками выполнения — это сильно затрагивает алгоритмы обработки данных.


К сожалению НИИ был настигнут молодым капитализмом с советским лицом и финансирование темы прикрыли. Работы через несколько лет продолжились и сейчас есть результаты — вот только люди, которые это делают рассказать ничего конкретного не могут — у них на работе интернета нет.
Re[2]: Многопоточность сегодня
От: сипласплас  
Дата: 10.10.07 18:39
Оценка:
Здравствуйте, Andrei F., Вы писали:

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


AF>А какие сейчас есть средства для синхронизации работы ядер? Можно ли например передавать данные между ядрами, не затрагивая при этом основную память? А то если диспетчеру придется постоянно делать полную синхронизацию всех кэшей, то это на корню убьет преимущества от распараллеливания, когда фрагменты задачи невелики по времени выполнения....


А разве каждое присваивание ссылки в c# не зовет что-то типа InterlockedExchangePointer?
Re[5]: Многопоточность сегодня
От: сипласплас  
Дата: 10.10.07 18:40
Оценка: 4 (1) +2
Здравствуйте, remark, Вы писали:

[]

R>Единственное, что будет быстрее в случае процессов — это однопоточный рантайм в каждом процессе. Но это из-за тупого реплицирования всех данных. Я думаю, что основная проблема тут это — аллокация памяти. Но я надеюсь, что ты не используешь стандартный аллокатор памяти из crt в многопоточных программах?


А какой надо использовать?

R>
Re[2]: Арифметика
От: сипласплас  
Дата: 10.10.07 18:52
Оценка:
Здравствуйте, remark, Вы писали:

[]

btw, после прочтения введения в lock/wait free Александреску мне показалось, что они хорошо ложатся на GC
Re: Многопоточность сегодня
От: iZEN СССР  
Дата: 10.10.07 19:48
Оценка: 16 (2) +2 -4
Здравствуйте, remark, Вы писали:

R>Уже достаточно давно программисты экстенсивно применяют многопоточность при реализации систем. При этом многопоточность применялась в основном для таких вещей как упрощение модели программирования, маскирование латентности блокирующих операций и т.д. И так же это всё происходило в подавляющем большинстве в контексте одного ядра/процессора. Соотв. распространены следующие принципы и подходы:

R> — Можно завести любое кол-во потоков. Иимеется в виду любое в пределах сотни. Т.е. кол-во потоков определяется исключительно потребностью архитектуры, но не аппаратной платформой.

Спорная посылка.
Количество потоков научились оформлять в пул и обычно проводят тестироание производительности в зависимости от размера пула.

R> — Можно произвольным образом распределить работу по потокам. Т.к. всё равно всё выполняется на одном ядре, то это не имеет значения.


Спорная посылка.
Девять рожениц никогда не родят одного дитя за один месяц.

R> — Можно и нужно экстенсивно применять мьютексы для синхронизации. Т.к. всё выполняется на одном ядре, то это практически не влияет на производительность и масштабируемость.


Никогда такого не было.
Блокировки всегда советовали применять, если по-другому нельзя. Избавление от блокировок где только можно -- одна из самых творческих и востребованных задач многопоточного программирования.
От GIANT_LOCK избавляются всеми доступными способами. Во FreeBSD, кстати, за минувший год проделана колоссальная работа по удалению глобальной блокировки в ядре.

R> — Можно произвольным образом разделять данные между потоками. Т.к. процессор один, то это никак не влияет на производительность и масштабируемость. Фактически система работает так, как будто поток один, просто он выполяет то одну функцию, то другую.


Спорная посылка.
Любая книжка по многопоточному программированию с 80-х годов ничего не говорит о том, что многопоточная программа будет выполнятся на одноядерном процессоре. Даже предположения приводятся противоположные: "А что будет, если ваша многопоточная программа будет выполняться на одном ядре -- будет велика вероятность взаимоблокировки на общих данных. Так что нужно делать так-то и так-то, чтобы этого не произошло.". У Таненбаума в книжках, кстати, есть масса примеров на этот счёт.
Так что ВСЕ_ВСЁ_ЗНАЛИ.

R>Всё это я называю «многопоточность на одном ядре». Фактически система, построенная по таким принципам, образно является «однопоточной с кооперативной многозадачностью».


Да.

R>И всё это становится кардинально не верным с появлением массовых многоядерных процессоров. Во второй половине следующего года Intel намерена выпустить процессор с 16 аппаратными потоками: здесь
Автор: remark
Дата: 20.09.07

R>И через 5 лет они собираются выпустить процессор с 80 ядрами! (Представть свои программы на 80 ядрах! Есть идеи как их использовать?)

Это область инноваций в код Windows, так как другие операционные системы более-менее переболели "одноядерностью" (MacOS 9 -> MacOS X; FreeBSD 4.x,5.x,6.x -> FreeBSD 7.0).

R>Что бы эффективно использовать новые аппаратные платформы, нужны совершенно новые принипы и подходы. Нужна «многопоточность на множестве ядер». Под эффективностью я подразумеваю, что бы программа на 8 ядрах выполнялась хотя бы не медленнее, чем на одном. Шутка шуткой, а на форумах посвящённым многопоточности сейчас один из самых распространённых вопросов «Почему моя программа, которая делает Х, на 4-ёх ядерной машине работает медленнее, чем на 1-ядерной?»


Это уже изобрели в Sun.
откройте для себя процессор UltraSPARC T1 (в UMA-среде) и программную архитектуру управления многопоточностью в Solaris 10. Ключевые слова: CMT, ThreadLiblaries, Light-weight process (LWP), Kernel Level threads, Thread Local Storage (TLS).

R>Потому что старые принципы многопоточности патологически не работают в новом контексте!


Это из пресс-релизов Intel так следует?

R>Я уверен, что значительная часть многопоточных систем «старой школы» будут быстрее работать на многоядерном процессоре, если банально привязать все потоки программы к одному ядру! Т.к. синхронизация всё равно убивает потенциальный параллелизм, а разделение данных вносит коллосальные пенальти.


R>Некоторое время назад я был свидетелем следующей ситуации. Серверное ПО запустили на двух-процессорной машине (в надежде, что оно будет работать в 2 раза быстрее. ха-ха). Оно стало работать в 10 (!) раз медленнее (как потом оказалось причиной было постоянное разделение модифицируемых данных между двумя потоками).



Это целиком зависит от профессионального мастерства программиста, пишущего многопоточное приложение. Обучены далеко не многие.
Возможно, Intel предлагает библиотеки, облегчающие процесс написания хорошо масштабируемых по нескольким вычислительным ядрам приложения. Это полезно в первую очередь новичкам. Но не станут ли они "дельфистами" от того, что научились писать приложения "мышкой"?

R>Сейчас наиболее общий рецепт выглядит примерно следующим образом:

R> — Создать кол-во потоков по кол-ву аппаратных потоков. Как следствие — кол-во потоков не должно быть «зашито» в программу, т.к. она может выполняться на разных платформах. И как второе следствие – управление кол-вом потоков не должно быть заботой прикладного программиста (ну по крайней мере того же программиста, но когда он играет роль прикладного ).

В общем представлении да, но как всегда, досадные мелочи всё ставят на свои места. Жаль, на них редко обращают внимание.

R> — Работа должна быть распределена по потокам [примерно] равномерно. Соотв. это тоже не получится зашивать в программу и поручать прикладному программисту, т.к. кол-во потоков и кол-во и содержание работы меняться.


Да.

R> — Нельзя экстенсивно применять мьютесы/синхронизацию/блокировки. Т.к. это фактически заставит систему сериализоваться и выполняться «на одном ядре». Ни о какой масштабируемости тут не может быть и речи.


Да. Всё должно быть в меру.

R> — По возможности надо элиминировать разделяемые данные. Совместная работа над одними модифицируемыми данными сейчас работает ооочень медленно и становится одним из важнейших новых боттлнеков аппаратной платформы, на ряду с тактами ядра, шиной к памяти, диском, сетью. И никаких изменений в лучшую сторону тут не предвидится. Только в худшую. (Это не относится к константным данным, их можно и нужно разделять между потоками)


Да.

R>Если выразить это более кратко: *каждое* ядро должно быть обеспечено *своей* работой и *своими* данными, и работать над ними *независимо*.

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

А как же прогресс в деле обSMPчивания MacOS? Ведь могут же на уровне операционки всё сделать красиво, а программисту-прикладнику оставить его работу!

<Остальное поскипано, так как говорить об том в рамках темы можно долго и нудно>
Re[2]: Многопоточность сегодня
От: сипласплас  
Дата: 10.10.07 20:00
Оценка:
Здравствуйте, iZEN, Вы писали:

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


R>>Уже достаточно давно программисты экстенсивно применяют многопоточность при реализации систем. При этом многопоточность применялась в основном для таких вещей как упрощение модели программирования, маскирование латентности блокирующих операций и т.д. И так же это всё происходило в подавляющем большинстве в контексте одного ядра/процессора. Соотв. распространены следующие принципы и подходы:

R>> — Можно завести любое кол-во потоков. Иимеется в виду любое в пределах сотни. Т.е. кол-во потоков определяется исключительно потребностью архитектуры, но не аппаратной платформой.

ZEN>Спорная посылка.

ZEN>Количество потоков научились оформлять в пул и обычно проводят тестироание производительности в зависимости от размера пула.

При чем здесь это?

R>> — Можно произвольным образом распределить работу по потокам. Т.к. всё равно всё выполняется на одном ядре, то это не имеет значения.


ZEN>Спорная посылка.

ZEN>Девять рожениц никогда не родят одного дитя за один месяц.

???

R>> — Можно и нужно экстенсивно применять мьютексы для синхронизации. Т.к. всё выполняется на одном ядре, то это практически не влияет на производительность и масштабируемость.


ZEN>Никогда такого не было.

ZEN>Блокировки всегда советовали применять, если по-другому нельзя. Избавление от блокировок где только можно -- одна из самых творческих и востребованных задач многопоточного программирования.
ZEN>От GIANT_LOCK избавляются всеми доступными способами. Во FreeBSD, кстати, за минувший год проделана колоссальная работа по удалению глобальной блокировки в ядре.

Где не было? Прочтите внимательнее. Это он о том, как _сейчас_ принято рассуждать

R>> — Можно произвольным образом разделять данные между потоками. Т.к. процессор один, то это никак не влияет на производительность и масштабируемость. Фактически система работает так, как будто поток один, просто он выполяет то одну функцию, то другую.


ZEN>Спорная посылка.

ZEN>Любая книжка по многопоточному программированию с 80-х годов ничего не говорит о том, что многопоточная программа будет выполнятся на одноядерном процессоре. Даже предположения приводятся противоположные: "А что будет, если ваша многопоточная программа будет выполняться на одном ядре -- будет велика вероятность взаимоблокировки на общих данных. Так что нужно делать так-то и так-то, чтобы этого не произошло.". У Таненбаума в книжках, кстати, есть масса примеров на этот счёт.
ZEN>Так что ВСЕ_ВСЁ_ЗНАЛИ.

Опять же, читаем внимательно к чему это.

[]
R>>И через 5 лет они собираются выпустить процессор с 80 ядрами! (Представть свои программы на 80 ядрах! Есть идеи как их использовать?)

ZEN>Это область инноваций в код Windows, так как другие операционные системы более-менее переболели "одноядерностью" (MacOS 9 -> MacOS X; FreeBSD 4.x,5.x,6.x -> FreeBSD 7.0).


Что значит переболели? Они выкидывают мьютексы и за тебя вставляют lock-free?

R>>Что бы эффективно использовать новые аппаратные платформы, нужны совершенно новые принипы и подходы. Нужна «многопоточность на множестве ядер». Под эффективностью я подразумеваю, что бы программа на 8 ядрах выполнялась хотя бы не медленнее, чем на одном. Шутка шуткой, а на форумах посвящённым многопоточности сейчас один из самых распространённых вопросов «Почему моя программа, которая делает Х, на 4-ёх ядерной машине работает медленнее, чем на 1-ядерной?»


ZEN>Это уже изобрели в Sun.

ZEN>откройте для себя процессор UltraSPARC T1 (в UMA-среде) и программную архитектуру управления многопоточностью в Solaris 10. Ключевые слова: CMT, ThreadLiblaries, Light-weight process (LWP), Kernel Level threads, Thread Local Storage (TLS).

И как это нам помогает писать быстрые мультитрэдные аппликухи?

[]

R>>Я уверен, что значительная часть многопоточных систем «старой школы» будут быстрее работать на многоядерном процессоре, если банально привязать все потоки программы к одному ядру! Т.к. синхронизация всё равно убивает потенциальный параллелизм, а разделение данных вносит коллосальные пенальти.


R>>Некоторое время назад я был свидетелем следующей ситуации. Серверное ПО запустили на двух-процессорной машине (в надежде, что оно будет работать в 2 раза быстрее. ха-ха). Оно стало работать в 10 (!) раз медленнее (как потом оказалось причиной было постоянное разделение модифицируемых данных между двумя потоками).


ZEN>Это целиком зависит от профессионального мастерства программиста, пишущего многопоточное приложение. Обучены далеко не многие.

ZEN>Возможно, Intel предлагает библиотеки, облегчающие процесс написания хорошо масштабируемых по нескольким вычислительным ядрам приложения. Это полезно в первую очередь новичкам. Но не станут ли они "дельфистами" от того, что научились писать приложения "мышкой"?

А что плохого, если они станут "дельфистами"?

[]

R>>Если выразить это более кратко: *каждое* ядро должно быть обеспечено *своей* работой и *своими* данными, и работать над ними *независимо*.

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

ZEN>А как же прогресс в деле обSMPчивания MacOS? Ведь могут же на уровне операционки всё сделать красиво, а программисту-прикладнику оставить его работу!


Что-то ты путаешь. Единственное, что может делать ОС — пытаться хорошо шедулить треды. Пока все. Все остальное должен делать девелопер.

ZEN><Остальное поскипано, так как говорить об том в рамках темы можно долго и нудно>


Прости, но все мимо кассы
Re[2]: Многопоточность сегодня
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 10.10.07 20:16
Оценка: 16 (3)
Здравствуйте, iZEN

<...все саркастические комментарии к посту remark-а поскипаны...>

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

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

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

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


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[5]: Многопоточность сегодня
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 10.10.07 20:21
Оценка: 12 (2)
Здравствуйте, remark, Вы писали:

R>Зато при использовании процессов ты гарантированно:

R> — Имеешь очень дорогое взаимодействие. Это скорее всего будет 2 системных вызова, 2 полных копирования данных, плюс ещё синхронизация и ещё куча непонятно чего. Более-менее не так ужасно тормозно это может быть только с IO-Lite:
R>http://www.usenix.org/publications/library/proceedings/osdi99/full_papers/pai/pai.pdf
R>Хотя его видимо никто не использует.
R>В случае же потоков это может действительно очень-очень-очень быстро. Порядка нескольких тактов.
R> — Имеешь копии read-mostly данных в памяти и каждого процесса. И в кэше.
R> — Имеешь сложность запуска/остановки/настройки приложения.

Зато имеешь возможно безболезненно килять сбойные процессы. Тогда как в многопоточном приложении придется убивать всех.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[3]: Многопоточность сегодня
От: Cyberax Марс  
Дата: 10.10.07 20:49
Оценка: 1 (1)
Здравствуйте, eao197, Вы писали:

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

А почему тут происходят переключения контекстов?
Sapienti sat!
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.