Pages:
Author

Topic: Могопоточное приложение на C++ - page 2. (Read 582 times)

newbie
Activity: 28
Merit: 6
Раз уж мы тут на криптофоруме, то можно порассуждать какая архитектура у биткоин коры... Так вот, если быть откровенном, то глядя на код который отвечает за клиент-серверное взаимодействие в коре, складывается устойчивое ощущение что сетевая архитектура у коры написана левой пяткой каким-то школьником, который первый раз в жизни вообще сетевое приложение пишет! Это ощущение складывается именно из-за кривой даже для 2007 года (когда Сатоши по его словам начал работать над кодом) многопоточности.
Код для работы с сетью в bitcoin core вполне себе асинхронный и всегда им был (раньше использовал системный вызов select, сейчас вроде как libevent, хотя на 100% не уверен), но оптимизированным его назвать сложно, т.к. он при обработке сообщения захватывает мьютекс cs_main, т.е. фактически однопоточный.
Quote from: Balthazar
Однако же, ничто не мешает реализовать асинхронное многопоточное приложение, если это действительно нужно. Главное - это иметь в виду, что оно не должно реализовываться тупым дублированием event loop на всех ядрах
Дублирование event loop на всех ядрах не всегда хорошо, особенно если ядер много (16 и больше), а если их, к примеру, 4, то вполне нормально запустить 4 потока с циклом сообщений, и в них же выполнять обработку этих сообщений.
legendary
Activity: 3108
Merit: 1359
Сильно сомневаюсь, что Сатоши - один человек, и вполне вероятно что Сатоши на форуме не имел отношения к непосредственно реализации программы, как таковой, он скорее руководитель проекта и его персонификация, если так можно сказать.

Биткойн клиент ещё при Гэвине был капитальным говнокодом, от изучения которого хотелось пустить себе 9 мм в лоб. Чего стоит синхронный броадкаст блоков, к примеру... Анонсируем блок одной ноде, получаем ответ, затем шлем блок если запросили. Потом шлем анонс следующей ноде, получаем ответ, затем шлем блок уже ей, если запросили. И так для каждого из подключенных пиров, последовательно, после чего каждый пир проделает этот же процесс уже для своих пиров. А то, что обмен данными с одним пиром никак не помешает обменяться этими же данными с другим пиром, автору в голову почему-то не пришло.



Радует, что всё это уже давно переписано и забыто.


Возвращаясь же к теме, многопоточность и асинхронность - это как теплое и мягкое, глупо сравнивать многопоточное синхронное приложение с асинхронным однопоточным. Грамотно написанное асинхронное приложение, если оно не использует блокирующие операции, действительно может работать настолько быстро, что не будет никакого смысла делать его многопоточную реализацию. Взять тот же redis, к примеру, производительность которого почти всегда ограничивается реализацией TCP/IP протокола.

Однако же, ничто не мешает реализовать асинхронное многопоточное приложение, если это действительно нужно. Главное - это иметь в виду, что оно не должно реализовываться тупым дублированием event loop на всех ядрах, потому что такой подход просто добавит глюков и геморроя, но проблему с производительностью никак не решит. Цикл не должен блокироваться в любом случае, а тяжелые задачи нужно выносить в отдельные потоки или процессы, обмен данными с которыми нужно реализовывать сообщениями или иным механизмом, который должен быть неблокирующим.
kzv
legendary
Activity: 1722
Merit: 1285
OpenTrade - Open Source Cryptocurrency Exchange
Та же упомянутая библиотека boost.asio позволяет запускать цикл обработки сообщений о завершенных операциях отправки/приема данных, ничто не мешает запустить таких потоков по количеству ядер, и обрабатывать эти сообщения одновременно.

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

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

Но еще раз повторяюсь: сервер это хоть и популярная, но на самом деле крайне специфичная, узкая задача. В этой задаче многопоточность имеет смысл, но естественно лишь по числу ядер в процессоре.

Раз уж мы тут на криптофоруме, то можно порассуждать какая архитектура у биткоин коры... Так вот, если быть откровенном, то глядя на код который отвечает за клиент-серверное взаимодействие в коре, складывается устойчивое ощущение что сетевая архитектура у коры написана левой пяткой каким-то школьником, который первый раз в жизни вообще сетевое приложение пишет! Это ощущение складывается именно из-за кривой даже для 2007 года (когда Сатоши по его словам начал работать над кодом) многопоточности.
Хотя если допустить, что Сатоши это Ник Сабо, то ничего удивительного - он ни разу не кодер, а скорее научный руководитель и вдохновитель ))
newbie
Activity: 28
Merit: 6
Что, прямо так мало задач распараллеливается? Smiley
Если посмотреть тест многоядерных процессоров (например 32-ядерного AMD) https://www.anandtech.com/show/15044/the-amd-ryzen-threadripper-3960x-and-3970x-review-24-and-32-cores-on-7nm то видно, что не так и мало бенчмарков, где он обгоняет обычные 6-8 ядерники с большим отрывом.
Серверы распарралеливаются почти все (не только веб), что мешает одновременно обрабатывать запросы от нескольких клиентов?
И причем тут вообще асинхронность? Та же упомянутая библиотека boost.asio позволяет запускать цикл обработки сообщений о завершенных операциях отправки/приема данных, ничто не мешает запустить таких потоков по количеству ядер, и обрабатывать эти сообщения одновременно.
kzv
legendary
Activity: 1722
Merit: 1285
OpenTrade - Open Source Cryptocurrency Exchange
но в контексте C++ написанное выглядит полным бредом Smiley Вот как можно противопоставлять многопоточность и асинхронность? Smiley Возьмем nginx, он асинхронный и многопоточный, в его конфиге указывается число рабочих потоков, и во многих случаях производительность линейно масштабируется в зависимости от кол-ва потоков.

Не порите чушь, ей больно ))
Противопоставлять многопоточность и асинхронность можно очень даже запросто и от языка программирования тут мало что зависит.
Не берите нгинкс, а напишите свой сервер в двух вариантах: в асинхронном и в многопоточном. Когда напишете - приходите, поговорим  Cheesy

Если серьезно, то многопоточность может давать какие-то преимущества за счет возможности распараллеливания некоторых (очень узкого круга) задач на многоядерных процессорах. Потому что под каждый поток операционная система может выделять отдельное ядро процессора.
Повторяю еще раз: очень мало есть реальных задач, где многопоточность может дать выигрыш в производительности. Веб сервер - как раз одна из таких немногих задач. Тот же нгинкс лучше настроить на работу в стольких потоках, сколько ядер у процессора где этот нгингкс крутится...
В большинстве же других задач, многопоточность только убивает производительность за счет всех этих мутексов-шмутексов и прочих семафоров...
newbie
Activity: 28
Merit: 6
Если что-то нужно распараллелить, то делить надо не на потоки, а на процессы. А параллелить внутри процесса.., ну я даже не могу представить себе для чего это может реально понадобиться... Разве что для какого-то специфичного стресс-теста многоядерного процессора.
Quote
Смотрите лучше в сторону оптимизации архитектуры. Многопоточность придумывали в те времена, когда еще были споры что лучше: многопоточность или асинхронность. К настоящему времени опытным путем давно установлено, что асинхронность всегда лучше.
Это смотря какой язык используется, если Python то из-за его особенностей это все правда, но в контексте C++ написанное выглядит полным бредом Smiley Вот как можно противопоставлять многопоточность и асинхронность? Smiley Возьмем nginx, он асинхронный и многопоточный, в его конфиге указывается число рабочих потоков, и во многих случаях производительность линейно масштабируется в зависимости от кол-ва потоков.
kzv
legendary
Activity: 1722
Merit: 1285
OpenTrade - Open Source Cryptocurrency Exchange
Я вам даю 100% гарантию, что при переходе на многопоточный режим, ваше приложение начнет "захлебываться" еще сильнее.
Смотрите лучше в сторону оптимизации архитектуры. Многопоточность придумывали в те времена, когда еще были споры что лучше: многопоточность или асинхронность. К настоящему времени опытным путем давно установлено, что асинхронность всегда лучше.
Разрабы биткоина кстати уже несколько лет пытаются окончательно выпилить boost из исходников, так что стоит задуматься: а вам оно точно надо?
jr. member
Activity: 320
Merit: 2
Примерно в 100% случаев, многопоточность делает приложению только хуже.
В данном случае, это не блаж - это необходимость.

Откуда такая уверенность?
И чем обусловлен выбор Boost.ASIO вместо например libev?
Если что-то нужно распараллелить, то делить надо не на потоки, а на процессы. А параллелить внутри процесса.., ну я даже не могу представить себе для чего это может реально понадобиться... Разве что для какого-то специфичного стресс-теста многоядерного процессора.

ASIO - так исторически сложилось. Делали форк с Bytecoin, там ASIO.
На одном ядре приложение захлебывается. В настоящее время самый оптимальный пусть масштабирования - это многопоточность (что бы потом можно было масштабировать производительность путем наращивания процессорных мощностей). Но столкнулись с проблемой при переходе на многопоточный режим ASIO. Нужен скилованный специалист, что бы оперативно решить вопрос, т.к. у самих получается медленно.

Про стресс-тест вообще не понял. ИМХО - неуместный сарказм. Многопоточность только для стресс-тестов придумывали что-ли?
kzv
legendary
Activity: 1722
Merit: 1285
OpenTrade - Open Source Cryptocurrency Exchange
Примерно в 100% случаев, многопоточность делает приложению только хуже.
В данном случае, это не блаж - это необходимость.

Откуда такая уверенность?
И чем обусловлен выбор Boost.ASIO вместо например libev?
Если что-то нужно распараллелить, то делить надо не на потоки, а на процессы. А параллелить внутри процесса.., ну я даже не могу представить себе для чего это может реально понадобиться... Разве что для какого-то специфичного стресс-теста многоядерного процессора.
jr. member
Activity: 320
Merit: 2
Примерно в 100% случаев, многопоточность делает приложению только хуже.
В данном случае, это не блаж - это необходимость.
kzv
legendary
Activity: 1722
Merit: 1285
OpenTrade - Open Source Cryptocurrency Exchange
Примерно в 100% случаев, многопоточность делает приложению только хуже.
jr. member
Activity: 320
Merit: 2
Многопоточное приложение на C++ с использованием Boost.ASIO.

Разыскивается опытный разработчик в указанной области.
Задача: перевести приложение с однопоточного режима во многопоточный.
Pages:
Jump to: