Собираюсь делать новый проект на C++, при этом планирую активно
применять распарраллеливание обработки данных за счёт многопоточности.
Приложение — прежде всего планируется для Windows, но если будет поддержка кроссплатформенности — то это дополнительное преимущество.
Планирую применение библиотеки классов Qt 5.6. По крайней мере для настольной версии приложения.
В связи с этои возникает вопрос:
Оптимальная (прежде всего с точки зрения производительности) реализация многопоточности:
1) При помощи функций WinAPI — вероятно, это самый производительный вариант, однако недостаток — нет кроссплатформенности;
2) Средствами Qt — QThread кроссплатформенность есть, вопрос по производительности не очевиден, доп-бонус — отсутствие сложного кода, как в п.1;
3) Средствами STL — std::thread (примерно та же картина как и во втором пункте).
Дополнительная красота третьего пункта — если будет серверное приложение, без GUI, то не нужно "притягивать за уши" доплнительные библиотеки.
Я расположил эти пункты в порядке выбора наиболее производительного (на мой взгляд) решения.
В проекте предполагается работа нескольких потоков, а также применение методов синхронизации потоков.
Актуален обмен данными между потоками.
Здравствуйте, AlexGin, Вы писали:
AG>Оптимальная (прежде всего с точки зрения производительности) реализация многопоточности: AG>1) При помощи функций WinAPI — вероятно, это самый производительный вариант, однако недостаток — нет кроссплатформенности; AG>2) Средствами Qt — QThread кроссплатформенность есть, вопрос по производительности не очевиден, доп-бонус — отсутствие сложного кода, как в п.1; AG>3) Средствами STL — std::thread (примерно та же картина как и во втором пункте).
Производительного?
Ты думаешь, Qt или stl будут делать лишнее переключение контекста? Думаешь, затраты на тред в Qt или stl больше пары-тройки уровней вложенности вызовов кода нативной платформы, т.е., в случае Windows — WinAPI?..
Я бы не парился и делал на самой удобной платформе, т.е., в твоём случае — на Qt. Всё равно на другой платформе без Qt не взлетит, значит, надо пользовать Qt на максимум.
Лучше бы над выбором примитивов синхронизации и политикой разграничения доступа к разделяемым ресурсам задумался -- вот, где больше вероятность просадить своё приложение по производительности.
Здравствуйте, Dair, Вы писали:
D>Производительного?
Ну я тут подразумеваю прежде всего производительность в работе средств синхронизации потоков.
D>Ты думаешь, Qt или stl будут делать лишнее переключение контекста? Думаешь, затраты на тред в Qt или stl больше пары-тройки уровней вложенности вызовов кода нативной платформы, т.е., в случае Windows — WinAPI?..
Думаю, что тут могут быть принципиальные различия — особенно в организации средств синхронизации потоков.
D>Я бы не парился и делал на самой удобной платформе, т.е., в твоём случае — на Qt.
+100500
D>Всё равно на другой платформе без Qt не взлетит, значит, надо пользовать Qt на максимум.
Не факт, что "без Qt не взлетит" — если делать серверную версию, то ИМХО возможно обойтись и проще.
Однако, я бы хотел все-таки выйти на применение Qt и для этого варианта.
Тем более, что применеие многопоточности для Qt окажется удобнее, чем "голый" STL.
AG>Ну я тут подразумеваю прежде всего производительность в работе средств синхронизации потоков.
Кто тебе мешает использовать какие-нибудь EnterCriticalSection в сочетании с Qt-thread'ами?
AG>Тем более, что применеие многопоточности для Qt окажется удобнее, чем "голый" STL.
Здравствуйте, b0r3d0m, Вы писали:
B>Лучше бы над выбором примитивов синхронизации и политикой разграничения доступа к разделяемым ресурсам задумался -- вот, где больше вероятность просадить своё приложение по производительности.
Все делается step by step — сначала прорабатываем алгоритмы обработки данных в однопоточном варианте;
затем — определяемся с многопоточностью — хотя бы на уровне выбора библиотек;
после этого — прорабатываем многопоточный алгоритм и его реализацию (о чем Вы и пишете выше).
AG>Все делается step by step — сначала прорабатываем алгоритмы обработки данных в однопоточном варианте; AG>затем — определяемся с многопоточностью — хотя бы на уровне выбора библиотек; AG>после этого — прорабатываем многопоточный алгоритм и его реализацию (о чем Вы и пишете выше).
Тогда берите наиболее подходящий по остальному проекту инструмент (если у вас везде Qt -- берите Qt, используете boost -- берите boost) и не парьтесь. Как только профилировщик / QA-инженер сообщит, что приложение не удовлетворяет требованиям по производительности, тогда и начинайте задумываться.
Здравствуйте, уважаемый b0r3d0m, Вы писали:
B>Кто тебе мешает использовать какие-нибудь EnterCriticalSection в сочетании с Qt-thread'ами?
Это теоретическое предположение, или есть Ваш опыт применения подобных решений?
Здравствуйте, b0r3d0m, Вы писали:
B>В boost мне, кстати, очень нравится одна встроенная деталь -- наличие interruption point'ов, которых нет ни в стандартной библиотеке C++, ни в Qt.
Спасибо, посмотрю в этом направлении!
Здравствуйте, b0r3d0m, Вы писали:
B>Тогда берите наиболее подходящий по остальному проекту инструмент (если у вас везде Qt -- берите Qt, используете boost -- берите boost) и не парьтесь. Как только профилировщик / QA-инженер сообщит, что приложение не удовлетворяет требованиям по производительности, тогда и начинайте задумываться.
Есть желание — выбрать наиболее верный путь на этапе проектирования, чтобы в будущем не "ломать все на корню", а тонко "доработать напильником".
AG>Это теоретическое предположение, или есть Ваш опыт применения подобных решений?
Был опыт совместного использования boost::thread и CriticalSection из WinAPI.
Дело в том, что boost::mutex в текущих версиях boost'а реализован на основе Event'ов, и при определённой организации многопоточности переход на критические секции может дать прирост производительности.
AG>Есть желание — выбрать наиболее верный путь на этапе проектирования, чтобы в будущем не "ломать все на корню", а тонко "доработать напильником".
Напишите свою абстрактную обёртку над потоками и используйте её в своём коде.
Здравствуйте, уважаемый b0r3d0m, Вы писали:
B>Был опыт совместного использования boost::thread и CriticalSection из WinAPI.
Это интересно!
B>Дело в том, что boost::mutex в текущих версиях boost'а реализован на основе Event'ов, и при определённой организации многопоточности переход на критические секции может дать прирост производительности.
+100500
Я подозреваю, что это же самое относится и к std::mutex!
AG>Я подозреваю, что это же самое относится и к std::mutex!
Нет, std::mutex реализован как раз на основе критических секций (по крайней мере, в Visual Studio 2013).
В любом случае, полагаться на детали реализации не стоит.
Здравствуйте, AlexGin, Вы писали:
D>>Производительного? AG>Ну я тут подразумеваю прежде всего производительность в работе средств синхронизации потоков.
Всё равно это же решается внутри ядра ОС, т.е., средствами WinAPI под Win.
D>>Ты думаешь, Qt или stl будут делать лишнее переключение контекста? Думаешь, затраты на тред в Qt или stl больше пары-тройки уровней вложенности вызовов кода нативной платформы, т.е., в случае Windows — WinAPI?.. AG>Думаю, что тут могут быть принципиальные различия — особенно в организации средств синхронизации потоков.
Qt и stl просто врапят для тебя WinAPIшные функции. Да, накладные расходы, наверно, есть, но, если ты не синхронизируешь тысячу потоков каждый такт, проблем быть не должно.
D>>Я бы не парился и делал на самой удобной платформе, т.е., в твоём случае — на Qt. AG>+100500
D>>Всё равно на другой платформе без Qt не взлетит, значит, надо пользовать Qt на максимум. AG>Не факт, что "без Qt не взлетит" — если делать серверную версию, то ИМХО возможно обойтись и проще.
Тогда stl. Или boost вообще, там это решено уже давно, вроде как.
Но я не boost не знаю совсем, но многие хвалят.
AG>Однако, я бы хотел все-таки выйти на применение Qt и для этого варианта. AG>Тем более, что применеие многопоточности для Qt окажется удобнее, чем "голый" STL.
Если ты не пишешь супер-highload, то Qt должен нормально справиться, равно как и stl.
Здравствуйте, Dair, Вы писали:
D>Здравствуйте, AlexGin, Вы писали:
D>>>Производительного? AG>>Ну я тут подразумеваю прежде всего производительность в работе средств синхронизации потоков.
D>Всё равно это же решается внутри ядра ОС, т.е., средствами WinAPI под Win.
Да, просто это может делаться разыими способами (так, например, синхронизировать потоки можно по-разному: мьютексом или крит/секцией).
D>>>Ты думаешь, Qt или stl будут делать лишнее переключение контекста? Думаешь, затраты на тред в Qt или stl больше пары-тройки уровней вложенности вызовов кода нативной платформы, т.е., в случае Windows — WinAPI?.. AG>>Думаю, что тут могут быть принципиальные различия — особенно в организации средств синхронизации потоков.
D>Qt и stl просто врапят для тебя WinAPIшные функции.
Это естественно так. D>Да, накладные расходы, наверно, есть, но, если ты не синхронизируешь тысячу потоков каждый такт, проблем быть не должно.
Тут могут быть принципиально различные решения одних и тех же задач синхронизации (и те и другие в конечном итоге вызовут ф-ции WinAPI).
D>>>Я бы не парился и делал на самой удобной платформе, т.е., в твоём случае — на Qt. AG>>+100500
D>>>Всё равно на другой платформе без Qt не взлетит, значит, надо пользовать Qt на максимум. AG>>Не факт, что "без Qt не взлетит" — если делать серверную версию, то ИМХО возможно обойтись и проще. D>Тогда stl. Или boost вообще, там это решено уже давно, вроде как. D>Но я не boost не знаю совсем, но многие хвалят.
Да, boost хорошая штука — думаю в этом направлении.
AG>>Однако, я бы хотел все-таки выйти на применение Qt и для этого варианта. AG>>Тем более, что применеие многопоточности для Qt окажется удобнее, чем "голый" STL. D>Если ты не пишешь супер-highload, то Qt должен нормально справиться, равно как и stl.
Спасибо, уважаемый Dair!
В общем — пока раздумываю.
Мои мысли о выборе — между boost и Qt.
Здравствуйте, AlexGin, Вы писали:
AG>Доброе время суток, уважаемые коллеги!
AG>Собираюсь делать новый проект на C++, при этом планирую активно AG>применять распарраллеливание обработки данных за счёт многопоточности.
... AG>Огромное спасибо, за любые мысли!
Здравствуйте, AlexGin, Вы писали:
AG>Доброе время суток, уважаемые коллеги!
AG>Собираюсь делать новый проект на C++, при этом планирую активно AG>применять распарраллеливание обработки данных за счёт многопоточности.
AG>Приложение — прежде всего планируется для Windows, но если будет поддержка кроссплатформенности — то это дополнительное преимущество. AG>Планирую применение библиотеки классов Qt 5.6. По крайней мере для настольной версии приложения.
AG>В связи с этои возникает вопрос: AG>Оптимальная (прежде всего с точки зрения производительности) реализация многопоточности: AG>1) При помощи функций WinAPI — вероятно, это самый производительный вариант, однако недостаток — нет кроссплатформенности; AG>2) Средствами Qt — QThread кроссплатформенность есть, вопрос по производительности не очевиден, доп-бонус — отсутствие сложного кода, как в п.1; AG>3) Средствами STL — std::thread (примерно та же картина как и во втором пункте). AG>Дополнительная красота третьего пункта — если будет серверное приложение, без GUI, то не нужно "притягивать за уши" доплнительные библиотеки.
AG>Я расположил эти пункты в порядке выбора наиболее производительного (на мой взгляд) решения. AG>В проекте предполагается работа нескольких потоков, а также применение методов синхронизации потоков. AG>Актуален обмен данными между потоками.
AG>Какие могут быть соображения по выбору?
AG>Огромное спасибо, за любые мысли!
Qt/stl/boost являются очень тонким обертками над API. Оверхед по производительности минимален.
Выбор между ними имеет смысл делать только в контексте будущего перенесения кода на другие платформы, другие компиляторы (в т.ч. устаревшие), выненесения библиотеки в другие приложения (не GUI) и т.д.
Для полноты картины (особенно для выч. математики) стоит рассмотреть:
OpenMP
TBB
Распараллеливание на уровне библиотек, решающих отдельные подзадачи. (Например, решение системы линейных уравнений.)
Причем это скорее именно "другие подходы", и если переписать приложение с QThread на std::thred довольно просто, то перейти с std::thred на OpenMP (или с него) почти невозможно. Но зато многие задаче в этом подходе решаются действительно на порядок проще.