Russian Qt Forum
Ноябрь 23, 2024, 20:15 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 [2]   Вниз
  Печать  
Автор Тема: QAtomicInt vs. QMutex  (Прочитано 16454 раз)
BRE
Гость
« Ответ #15 : Сентябрь 14, 2011, 11:46 »

Мутекс блокирует нитки, атомарные операции нет, эти вещи не взаимозаменяемы.
Ну и что. Что это меняет, если например нужно из разных потоков инкрементировать переменную?  Строит глазки
Сравнивать их самих по себе может и бессмысленно, а вот решения с их использованием сравнивать можно вполне.

Записан
BRE
Гость
« Ответ #16 : Сентябрь 14, 2011, 12:05 »

Но если изменить алгоритм и ..
Ну так это может быть очень недешево (с точки зрения написания)
Очень важно звучащая фраза... "недешево с точки зрения написания"... Улыбающийся
Только у меня от нее остается осадочек... что она означает - лучше сделать как попало но дешево, чем подумать и сделать хорошо и дорого.
Записан
brankovic
Гость
« Ответ #17 : Сентябрь 20, 2011, 16:32 »

Но если изменить алгоритм и каждой нитке указать диапазон вектора для заполнения, то они все сразу заработают параллельно не мешая друг другу (да и объекты синхронизации уже не понадобятся).

1. много тредов делающих конкурирующие атомарки (т.е. в одной кэш линии), работают медленне, чем один тред делающий то же самое. Проверенно на 16-корной машине (в 2 раза где-то в моём примере было). А всё от того, что там тоже мьютексы, только на уровне шины процессора.

2. синхронизация всё равно всегда нужна, чтобы гарантировать время жизни объекта хотя бы

Очень важно звучащая фраза... "недешево с точки зрения написания"... Только у меня от нее остается осадочек... что она означает - лучше сделать как попало но дешево, чем подумать и сделать хорошо и дорого.

3. определяется колличественно в деньгах. Лучше всего сразу знать насколько хорошо нужно сделать и делать ровно на столько хорошо. Тут главное: поток задач бесконечен, если на всё тратить много времени, то легко отстать от жизни. Если двигаться слишком быстро, то легко растерять доверие клиентов из-за багов.

P.S.: да, ещё кьютишные мьютексы это чёрный ящик, на винде и на posix работают совершенно по-разному. На винде нативный мьютекс это объект межпроцессного взаимодействия. Аналогом pthread_mutex скорее является CRITICAL_SECTION. По-моему лучше быть настороже имея дело с обёрткой, чем свято верить в "QMutex" == "какой-то другой мьютекс".
« Последнее редактирование: Сентябрь 20, 2011, 16:54 от brankovic » Записан
BRE
Гость
« Ответ #18 : Сентябрь 20, 2011, 17:11 »

1. много тредов делающих конкурирующие атомарки (т.е. в одной кэш линии), работают медленне, чем один тред делающий то же самое. Проверенно на 16-корной машине (в 2 раза где-то в моём примере было). А всё от того, что там тоже мьютексы, только на уровне шины процессора.

2. синхронизация всё равно всегда нужна, чтобы гарантировать время жизни объекта хотя бы

Я говорил о том, что скажем вектор из 1000 элементов можно заполнять несколькими потоками, выделив каждому потоку по своему диапазону.
Например, поток #1 - заполняет элементы от 0 до 249, поток # 2 - 250..499 и т.д.
Под заполнением подразумевается какие-то вычисления и запись результата.
На нескольких ядрах это будет быстрее чем на одном и синхронизировать там нечего будет.
Записан
BRE
Гость
« Ответ #19 : Сентябрь 20, 2011, 17:21 »

P.S.: да, ещё кьютишные мьютексы это чёрный ящик, на винде и на posix работают совершенно по-разному. На винде нативный мьютекс это объект межпроцессного взаимодействия. Аналогом pthread_mutex скорее является CRITICAL_SECTION. По-моему лучше быть настороже имея дело с обёрткой, чем свято верить в "QMutex" == "какой-то другой мьютекс".
Ну как бы верить вообще не во что не надо. Улыбающийся
Что требуется от QMutex? То что бы он выполнял возложенные на него задачи и делал это максимально эффективно на каждой из поддерживаемых платформ. А как он это будет делать - это его тяжелые будни. Улыбающийся

Записан
brankovic
Гость
« Ответ #20 : Сентябрь 20, 2011, 18:07 »

Что требуется от QMutex? То что бы он выполнял возложенные на него задачи и делал это максимально эффективно на каждой из поддерживаемых платформ. А как он это будет делать - это его тяжелые будни. Улыбающийся

правильно, только в жизни порой оказывается, что делает "n-ская непрозрачная либа" своё дело плохо. Поэтому обсуждать кьютный мьютекс вполне логично, как обсуждать http сервер PoCo, например. Все http сервера делают в теории одно и то же, а на практике делают, но по-разному.

В частности упомянутый QMutex под винду делает что-то страшное, посмотрите код. Мне кажется там баг, но возможности проверить лень.
Записан
BRE
Гость
« Ответ #21 : Сентябрь 20, 2011, 18:10 »

но возможности проверить лень.
У меня тоже возможности проверить лень. Улыбающийся  /* неплохая фраза получилась Улыбающийся */
+ нужно будет вспоминать/читать как-там что вообще в венде делается.
« Последнее редактирование: Сентябрь 20, 2011, 20:44 от BRE » Записан
Akon
Гость
« Ответ #22 : Сентябрь 20, 2011, 20:42 »

Тоже был удивлен, когда увидел, что QMutex не пользует эффективный CRITICAL_SECTION, а сразу лезет к ядру, что значительно дороже. Прочем, в такой реализации возможны условные переменные на мьютексе (QWaitCondition), а на CRITICAL_SECTION они не возможны. Имхо, QMutex сделан достаточно просто/универсалено, и в силу этого он не оптимален в некоторых аспектах.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #23 : Сентябрь 21, 2011, 11:24 »

Очень важно звучащая фраза... "недешево с точки зрения написания"... Улыбающийся
Только у меня от нее остается осадочек... что она означает - лучше сделать как попало но дешево, чем подумать и сделать хорошо и дорого.
Ну за примером ходить недалеко http://www.prog.org.ru/index.php?topic=19399.msg130940#msg130940. Попробуем применить Ваши рекомендации (которые впрочем в данном случае совпадают с моими как видно из топика)

Я говорил о том, что скажем вектор из 1000 элементов можно заполнять несколькими потоками, выделив каждому потоку по своему диапазону.
Например, поток #1 - заполняет элементы от 0 до 249, поток # 2 - 250..499 и т.д.
Под заполнением подразумевается какие-то вычисления и запись результата.
На нескольких ядрах это будет быстрее чем на одном и синхронизировать там нечего будет.
1) Вектор из элементов сначала надо создать - пробежаться по директориям в данном примере. Это может быть совсем  не быстро если напр для поиска выбран том. Если уж "делать хорошо", то надо начинать сканирование с корня и затем углубляться - нередко интересующий пользователя результат может быть найден быстро.

2) Есть такое словечко "гранулярность" - все хорошо если все задачи/кластеры выполняются за примерно одинаковое время, и наоборот. Попадется напр системный файл swap (да хотя бы просто большой sbr файл на Вындоуз) - и "быстрее" сведется к нулю.

Конечно эти (и другие) проблемы можно решить - но ценой дальнейшего усложнения. Заметим что если мы бы могли безболезненно делать put/get в общий контейнер - все было бы куда проще.

Ну как бы верить вообще не во что не надо. Улыбающийся
Что требуется от QMutex? То что бы он выполнял возложенные на него задачи и делал это максимально эффективно на каждой из поддерживаемых платформ. А как он это будет делать - это его тяжелые будни. Улыбающийся
"Вообще говоря" этот подход хорош - невозможно (да и не нужно) вникать во все детали реализации. Но есть исключения, и они бывают часто. Прямолинейно используя "честный мутекс" можно оказаться в неудобном положении  Улыбающийся
 
Записан
BRE
Гость
« Ответ #24 : Сентябрь 21, 2011, 11:33 »

Прямолинейно используя "честный мутекс" можно оказаться в неудобном положении  Улыбающийся
Так никто не заставляет его использовать всегда и прямолинейно.
QMutex в Qt сделан так, что бы на всех поддерживаемых платформах работать одинаково.
Почему на венде он сделан именно так, мне кажется правильно ответил Akon:
Цитировать
в такой реализации возможны условные переменные на мьютексе (QWaitCondition), а на CRITICAL_SECTION они не возможны.

Но если для какого-то алгоритма лучше подойдут критические секции, то можно (и нужно) сделать:
Код
C++ (Qt)
#ifdef WIN32
...
#else
...
#endif
 
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #25 : Сентябрь 21, 2011, 11:34 »

1. много тредов делающих конкурирующие атомарки (т.е. в одной кэш линии), работают медленне, чем один тред делающий то же самое. Проверенно на 16-корной машине (в 2 раза где-то в моём примере было). А всё от того, что там тоже мьютексы, только на уровне шины процессора.
Не знаю что такое "атоиарка" (иномарка или ГАЗ ? Улыбающийся) но я был весьма удивлен обнаружив что атомарный лок также тормозит (и может быть неприемлем) если конкуренция достаточно велика.
Записан
Страниц: 1 [2]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.139 секунд. Запросов: 23.