powered by simpleCommunicator - 2.0.59     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Какие из методов std::shared_ptr из нового стандарта потокобезопасны?
25 сообщений из 33, страница 1 из 2
Какие из методов std::shared_ptr из нового стандарта потокобезопасны?
    #38028889
std::shared_ptr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Какие из методов std::shared_ptr из нового стандарта C++11 потокобезопасны и что подразумевается под "многопоточный вариант shared_ptr" и "озаботившись указать для shared_ptr быстрый pool-аллокатор"?
http://habrahabr.ru/post/131478/#comment_4365579
автор1. Это слишком медленно в языках, где ВСЕ является ссылкой (аналог С++ — все обернуто в shared_ptr). На С++ так пишут только неадекватные товарищи типа некоторых лисперов).
2. Инкремент и декремент счетчика быстрые, пока приложение однопоточное. Основные тормоза дают new — выделение памяти в куче, и delete во время равенства ссылки нулю.
3. Это важный момент — не сам подсчет ссылок тормозит, а аллокатор.
4. Наиболее частая операция для умного указателя — разыменование — такая же по скорости, как для тупого.

Так что тормоза сделать можно только весьма искусственно — оборачивать все в многопоточный вариант shared_ptr, и это все постоянно создавать и уничтожать, не озаботившись указать для shared_ptr быстрый pool-аллокатор.
...
Рейтинг: 0 / 0
Какие из методов std::shared_ptr из нового стандарта потокобезопасны?
    #38029011
sherzod_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
std::shared_ptr,

вольный пересказ стандарта:

В смысле потокобезопасности std::shared_ptr ведет себя точно как встроенные типы. Чтение безопасно, запись из каждого потока в отдельный экземпляр соответственно - безопасно, все остальные случаи ведут к неопределенному поведению. Существуют стандартные функции для потокобезопасного доступа к std::shared_ptr. Начинаются с префикса atomic_, устанавливают, сбрасывают, обменивают значение. Посмотрите в справочнике.

Многопоточный вариант возможно означает какую-то самописную реализацию с внутренними блокировками для экслюзивного доступа.

Pool-аллокатор возможно означает самописный аллокатор - надстройку над стандартными функциями работы с памятью для повышения скорости выделения и освобождения памяти. Не очень понятно как это вообще относится к shared_ptr.

Да и мало ли что пишут в комментариях, по мне так просто набор "умных" слов человек выложил. Утверждение "тормозит аллокатор а не подсчет ссылок", весьма и весьма спорное, например при передаче в какую-либо многопоточную очередь важно быстрое копирование разделяемого указателя, многопоточный вариант будет работать намного медленнее при том что очередь уже сама организует безопасную вставку, извлечение.
...
Рейтинг: 0 / 0
Какие из методов std::shared_ptr из нового стандарта потокобезопасны?
    #38029046
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
std::shared_ptrКакие из методов std::shared_ptr из нового стандарта C++11 потокобезопасны и что подразумевается под "многопоточный вариант shared_ptr" и "озаботившись указать для shared_ptr быстрый pool-аллокатор"?
http://habrahabr.ru/post/131478/#comment_4365579

Если к каждой их нескольких копий shared_ptr, ссылающихся на один объект, обращаться только из одного потока то все операции с копией - потокобезопасны.
Если несколько потоков обращаются к одной копии shared_ptr, то потокобезопасно только если все потоки только читают (разыменовывают).
"многопоточный вариант shared_ptr" - вариант в котором счетчик ссылок атомарно меняется. В бусте есть (или уже была) опция которая убирает атомарность и связанный с этим оверхед, если вы не планируете несколько потоков иметь.
Но по умолчанию - многопоточность shared_ptr включена.

автор1. Это слишком медленно в языках, где ВСЕ является ссылкой (аналог С++ — все обернуто в shared_ptr). На С++ так пишут только неадекватные товарищи типа некоторых лисперов).
2. Инкремент и декремент счетчика быстрые, пока приложение однопоточное. Основные тормоза дают new — выделение памяти в куче, и delete во время равенства ссылки нулю.
3. Это важный момент — не сам подсчет ссылок тормозит, а аллокатор.
4. Наиболее частая операция для умного указателя — разыменование — такая же по скорости, как для тупого.

Так что тормоза сделать можно только весьма искусственно — оборачивать все в многопоточный вариант shared_ptr, и это все постоянно создавать и уничтожать, не озаботившись указать для shared_ptr быстрый pool-аллокатор.
На самом деле все утвеждения кроме п.4 высосаны из пальца.

1. Нет никаких причин по умолчанию не использовать shared_ptr (при совместном владении) или unique_ptr (при одном владельце). Наоборот, скорее неадекватны те кто используют raw-указатель когда доступны умные - это отказ от бесплатной потоко- и исключение-безопасности.

2. В типичном приложении сколько бы ни было потоков, к одному объекту редко когда обращаются во многих потоках. Обычно 1-2 потока (создание-обработка).
В этом случае атомарный (многопоточный) ин/декремент не тормозит.
Оверхед на выделение памяти для нужд самого shared_ptr устраняется использованием make_shared который выделяет и объект и счетчик ссылок в одной операции. А оверхед создания самого объекта бессмысленно в данном контексте рассматривать т.к. объект по-любому надо создавать хоть с простыми хоть умными указателями.

3. Использовать make_shared (а не какой-то там пул, реализацию которого еще найти надо на всех платформах)

Итого - при правильном использовании никаких тормозов из-за shared_ptr нет.
...
Рейтинг: 0 / 0
Какие из методов std::shared_ptr из нового стандарта потокобезопасны?
    #38029058
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sherzod_например при передаче в какую-либо многопоточную очередь важно быстрое копирование разделяемого указателя, многопоточный вариант будет работать намного медленнее при том что очередь уже сама организует безопасную вставку, извлечение.
Многопоточный подсчет ссылок внутри shared_ptr нужен независимо от блокировки контейнера.
Например если один поток вставил в очередь, а другой прочитал, то мы имеет 2 копии указателя.
Теперь если оба потока удалят свою копию, то счетчик ссылок должен атомарно отработать, т.к. удаление копий уже не защищено блокировкой очереди.
...
Рейтинг: 0 / 0
Какие из методов std::shared_ptr из нового стандарта потокобезопасны?
    #38029075
sherzod_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
[quot Anatoly Moskovsky]sherzod_Многопоточный подсчет ссылок внутри shared_ptr нужен независимо от блокировки контейнера. Например если один поток вставил в очередь, а другой прочитал, то мы имеет 2 копии указателя. Теперь если оба потока удалят свою копию, то счетчик ссылок должен атомарно отработать, т.к. удаление копий уже не защищено блокировкой очереди. Ну конечно торможу, выражал мысль что копирование медленное, недавно использовал unique_ptr в очереди видимо контекст в голове еще тот, пример растолковал неверно.
...
Рейтинг: 0 / 0
Какие из методов std::shared_ptr из нового стандарта потокобезопасны?
    #38029201
std::shared_ptr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly MoskovskyНо по умолчанию - многопоточность shared_ptr включена.
И в std тоже включена по умолчанию? А как отключить её в std?

Т.е. по умолчанию безопасно удаление, чтение, разыменовывание и копирование из общего между потоками экземпляра shared_ptr. И затем любая работа с ним в своей копии в пределах одного потока.
А не безопасно только присваивание нового указателя в общий экземпляр shared_ptr ну и собственно не безопасен сам объект на который указывает shared_ptr?
...
Рейтинг: 0 / 0
Какие из методов std::shared_ptr из нового стандарта потокобезопасны?
    #38029236
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
std::shared_ptrAnatoly MoskovskyНо по умолчанию - многопоточность shared_ptr включена.
И в std тоже включена по умолчанию? А как отключить её в std?

Зачем?

Т.е. по умолчанию безопасно удаление, чтение, разыменовывание и копирование из общего между потоками экземпляра shared_ptr.
С чего вы взяли что это безопасно?
Для общего экземпляра безопасно только чтение (включая разыменовывание и копирование).
Если же хотя бы один поток может присваивать или удалять объект в общем экземпляре указателя, то тогда воообще все операции включая чтение должны быть защищены внешним мьютексом.
...
Рейтинг: 0 / 0
Какие из методов std::shared_ptr из нового стандарта потокобезопасны?
    #38029239
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
std::shared_ptrAnatoly MoskovskyНо по умолчанию - многопоточность shared_ptr включена.
И в std тоже включена по умолчанию? А как отключить её в std?

Опцию отключения в бусте делали для платформ где нельзя lock-free инкременты делать, и они были реализованы через стандартные мьютексы - это действительно имело большой оверхед.
На всех современных платформах есть lock-free инкременты, которые вносят несущественный оверхед, чтобы заботиться об отключении в однопоточном случае.
...
Рейтинг: 0 / 0
Какие из методов std::shared_ptr из нового стандарта потокобезопасны?
    #38029256
std::shared_ptr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly Moskovskystd::shared_ptrпропущено...

И в std тоже включена по умолчанию? А как отключить её в std?

Опцию отключения в бусте делали для платформ где нельзя lock-free инкременты делать, и они были реализованы через стандартные мьютексы - это действительно имело большой оверхед.
На всех современных платформах есть lock-free инкременты, которые вносят несущественный оверхед, чтобы заботиться об отключении в однопоточном случае.
Но это же в любом случае кэш пинг-понг, а именно из-за него не стали добавлять shared_mutex в std, т.к. именно из-за него по мнению авторов boost:thread разделяемый мьютекс медленней обычного мьютекса даже на операциях чтения. Т.е. они посчитали lock-free менее производительным чем обычный мьютекс.
...
Рейтинг: 0 / 0
Какие из методов std::shared_ptr из нового стандарта потокобезопасны?
    #38029303
std::shared_ptr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
http://permalink.gmane.org/gmane.comp.lib.boost.devel/211180
Вот кстати про почему нет std::shared_mutex.
...
Рейтинг: 0 / 0
Какие из методов std::shared_ptr из нового стандарта потокобезопасны?
    #38029450
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
std::shared_ptrAnatoly MoskovskyНа всех современных платформах есть lock-free инкременты, которые вносят несущественный оверхед, чтобы заботиться об отключении в однопоточном случае.
Но это же в любом случае кэш пинг-понг, а именно из-за него не стали добавлять shared_mutex в std, т.к. именно из-за него по мнению авторов boost:thread разделяемый мьютекс медленней обычного мьютекса даже на операциях чтения. Т.е. они посчитали lock-free менее производительным чем обычный мьютекс.
Не может быть просто мютекс быстрее чем шаред мьютек из-за локфри, потому что и там и там переключение мьютекса производится одной и той же атомарной операцией. По другому просто нельзя сделать.

Это я к чему.
Сели две группы людей: одни криворукие написали тормознутую реализацию shared_mutex, другие слепые не смогли там разглядеть что тормозит и не включили в стандарт потому что подумали что те криворукие самые умные и быстрее сделать нельзя.
А между тем была еще одна группа, которая в Windows Vista реализовала свой shared_mutex (под названием slim read/write lock), который размером всего в один указатель, и работает быстрее чем boost::mutex. А там простой юзермод локфри - тот который якобы медленнее мьютекса.
...
Рейтинг: 0 / 0
Какие из методов std::shared_ptr из нового стандарта потокобезопасны?
    #38029475
std::shared_ptr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly Moskovskystd::shared_ptrпропущено...

Но это же в любом случае кэш пинг-понг, а именно из-за него не стали добавлять shared_mutex в std, т.к. именно из-за него по мнению авторов boost:thread разделяемый мьютекс медленней обычного мьютекса даже на операциях чтения. Т.е. они посчитали lock-free менее производительным чем обычный мьютекс.
Не может быть просто мютекс быстрее чем шаред мьютек из-за локфри, потому что и там и там переключение мьютекса производится одной и той же атомарной операцией. По другому просто нельзя сделать.

Это я к чему.
Сели две группы людей: одни криворукие написали тормознутую реализацию shared_mutex, другие слепые не смогли там разглядеть что тормозит и не включили в стандарт потому что подумали что те криворукие самые умные и быстрее сделать нельзя.
А между тем была еще одна группа, которая в Windows Vista реализовала свой shared_mutex (под названием slim read/write lock), который размером всего в один указатель, и работает быстрее чем boost::mutex. А там простой юзермод локфри - тот который якобы медленнее мьютекса.
Вполне допускаю, что так. Потом в POSIX тоже есть pthread_rwlock_t, правда не знаю как он относительно реализации из Vista. Но странно, неужели там столько криворуких "умных"? :)

Сам я не помню тестировал или нет, могу предположить, что мьютекс просто будет вызываться реже, т.к. при средней конкуренции мьютекс остановит на всех ядрах кроме одного все потоки связанные с блокируемым объектом/кодом на относительно длинное время, за которое активный поток на одном и том же ядре успеет захватить и отпустить мьютекс несколько раз.
Либо как вариант, т.к. мьютекс это ОС, то она видя какие потоки чем блокируются, перекинет их по возможности на одно ядро/один процессор.
...
Рейтинг: 0 / 0
Какие из методов std::shared_ptr из нового стандарта потокобезопасны?
    #38029490
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
std::shared_ptr,

Я ж уже написал. Разница в скорости между бустовскими mutex и shared_mutex не из-за так называемого пингпонга (который есть в обоих случаях), а из-за громоздкой, нафарширванной ненужными фичами реализации shared_mutex.
Вот бенчмарки: http://askldjd.wordpress.com/2011/03/06/performance-comparison-on-reader-writer-locks/

Возвращаясь к счетчику ссылок.
Если взять голый атомарный счетчик, то он безусловно быстрее простого счетчика защищенного любым видом мьютекса.
Что тут еще обсуждать?
...
Рейтинг: 0 / 0
Какие из методов std::shared_ptr из нового стандарта потокобезопасны?
    #38029659
sherzod_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyНе может быть просто мютекс быстрее чем шаред мьютек из-за локфри, потому что и там и там переключение мьютекса производится одной и той же атомарной операцией. По другому просто нельзя сделать.

Это я к чему.
Сели две группы людей: одни криворукие написали тормознутую реализацию shared_mutex, другие слепые не смогли там разглядеть что тормозит и не включили в стандарт потому что подумали что те криворукие самые умные и быстрее сделать нельзя.
А между тем была еще одна группа, которая в Windows Vista реализовала свой shared_mutex (под названием slim read/write lock), который размером всего в один указатель, и работает быстрее чем boost::mutex. А там простой юзермод локфри - тот который якобы медленнее мьютекса.

Я ж уже написал. Разница в скорости между бустовскими mutex и shared_mutex не из-за так называемого пингпонга (который есть в обоих случаях), а из-за громоздкой, нафарширванной ненужными фичами реализации shared_mutex.
Вот бенчмарки: http://askldjd.wordpress.com/2011/03/06/performance-comparison-on-reader-writer-locks/

Возвращаясь к счетчику ссылок.
Если взять голый атомарный счетчик, то он безусловно быстрее простого счетчика защищенного любым видом мьютекса.
Что тут еще обсуждать?
По моему в том обсуждении выражалась немного другая мысль. Простая мысль о том что как ни крути, shared_mutex будет намного намного медленнее при выполнении как ни парадоксально именно задачи для него предназначенной, и именно из-за интенсивного обмена кэш-линиями между ядрами. Также говориться о том что это хорошо std::shared_mutex не был принят, по вышеуказанной причине, и что в каждом случае есть лучшее решение чем read/write lock.

По-моему нет сомнений что кэш-пинг-понг будет при read lock-ах. Так как состояние мьютекса хранится в разделяемой ячейке памяти а каждый read-lock (!) также меняет это состояние следовательно CPU меняющее это состояние должен известить остальные о том что кэш-линия содержащая это состояние устарела. При этом парадокс заключается в том что чем больше будет параллельных read-lock-ов, те чем большее кол-во ядер будет задействовано, тем интенсивнее будет обмен кэш-линиями, тем медленнее будет захват мьютекса.

Насчет приведенных бенчмарков. Мысль о том что boost::shared_mutex просто сделан плохо, возможно верная (я лично так не думаю, сколько не искал не нашел детали реализации vista slim rw lock), но просто это не имеет значения. На фоне мысли о том что сама идея shared_mutex-а недостаточно оправдана для включения в стандарт, и имеет лучшие альтернативные решения.
...
Рейтинг: 0 / 0
Какие из методов std::shared_ptr из нового стандарта потокобезопасны?
    #38029743
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sherzod_По моему в том обсуждении выражалась немного другая мысль. Простая мысль о том что как ни крути, shared_mutex будет намного намного медленнее при выполнении как ни парадоксально именно задачи для него предназначенной, и именно из-за интенсивного обмена кэш-линиями между ядрами.
Намного медленнее чего ? Просто мьютекса?
Обычный мьютекс имеет те же самые проблемы что и шаред.
Точно так же при каждом захвате и освобождениии мьютекса происходят обновления кешей ядер.
Говорить о том что шаред мьютекс принципиально медленнее обычного - нонсенс.
...
Рейтинг: 0 / 0
Какие из методов std::shared_ptr из нового стандарта потокобезопасны?
    #38029824
sherzod_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyНамного медленнее чего ? Просто мьютекса?
Обычный мьютекс имеет те же самые проблемы что и шаред.
Точно так же при каждом захвате и освобождениии мьютекса происходят обновления кешей ядер.
Говорить о том что шаред мьютекс принципиально медленнее обычного - нонсенс.
Анатолий, попробуйте смоделировать ситуацию о которой говориться в обсуждении. А именно ситуацию когда есть много мелких параллельных чтений одного и того же ресурса (скажем разделяемой памяти или порта). Чтение этой памяти будет последовательным, что в сущности выстроит все потоки в очередь.

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

Теперь представим что ресурс защищен простым мьютексом. Один поток захватит мьютекс и вызовет обновление кэш-линий других. Все остальные теперь просто заблокируются, будут ждать сигнала condition variable. Ни один из них (остальных) не вызовет обновление кэш линий. Захвативший поток отпускает мьютекс, вызывает обновление кэш линий изменяет condition variable. Ситуация повторяется сначала.

И это ведь мы рассмотрели на "атомарном" уровне все. В реальном времени все умножится и даст миллионы обновлений против сотен тысяч. Разница в разы. Так же в той беседе говорится что при редкий чтениях та же ситуация просто растягивается во времени и эффект просто виден меньше. Не думаю что в комитете сидят идеальные существа без возможности ошибиться, но люди довольно ответственные, принимающие решения не просто так.
...
Рейтинг: 0 / 0
Какие из методов std::shared_ptr из нового стандарта потокобезопасны?
    #38029909
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sherzod_Anatoly MoskovskyНамного медленнее чего ? Просто мьютекса?
Обычный мьютекс имеет те же самые проблемы что и шаред.
Точно так же при каждом захвате и освобождениии мьютекса происходят обновления кешей ядер.
Говорить о том что шаред мьютекс принципиально медленнее обычного - нонсенс.
Анатолий, попробуйте смоделировать ситуацию о которой говориться в обсуждении. А именно ситуацию когда есть много мелких параллельных чтений одного и того же ресурса (скажем разделяемой памяти или порта). Чтение этой памяти будет последовательным, что в сущности выстроит все потоки в очередь.

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

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

Если же опять вернуться к счетчику ссылок от которого вы постоянно куда-то в сторону уводите, то как я уже выше объяснял в типичном многопоточном приложении кол-во копий смартуказателя в разных потоках в среднем 1 и не превышает 2. А в однопоточном - ровно 1. И поэтому все рассуждения что зашита счетчика мьютексом быстрее чем просто атомарный инкремент (напомню в среднем без конкурирующих потоков) - нонсенс. С мьютексом будет две записи во внешнюю память+оверхед на обработку состояния мьютекса (в частности условный переход который может приводить к сбою предсказания переходов), а с атомарным инкрементом - просто одна безусловная запись, которая от обычного неатомарного инкремента отличается всего лишь парой дополнительных циклов на блокировку шины.
Поэтому возвращаясь к тому с чего началось - отключать многопоточность подсчета ссылок в shared_ptr нет смысла.
...
Рейтинг: 0 / 0
Какие из методов std::shared_ptr из нового стандарта потокобезопасны?
    #38030087
sherzod_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovskysherzod_пропущено...

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

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

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

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

Я всего лишь пытаюсь оспорить два ваших замечания:

1. shared_mutex не приняли в стандарт из-за кривой реализации в boost.
2. shared_mutex быстрее просто mutex.

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

Ваше утверждение что при длительной операции чтения boost::shared_mutex быстрее boost::mutex тоже безосновательно. Хотелось увидеть разбор причин, почему он должен быть быстрее. Выше я процитировал причины названные разработчиком posix threads по которым разделяемый мьютекс должен быть медленнее.

Ваше предположение о том что читаемая память будет в кэше не совсем верное. А если верное то это именно тот случай когда не следует применять shared_mutex. Мы ведь рассматриваем сценарий много читающих, мало или один записывающий. Без лишних объяснений думаю уже поймете что в таком сценарии нужно предотвратить кеширование читаемого/записываемого ресурса (volatile?). Зачем много раз читать то что не изменилось? Один обновил, многие считали, тут обращение к внешней памяти неизбежно. Поэтому все рассуждения (кстати не мои) про последовательный доступ к ресурсу остаются в силе, не говоря уже о случаях когда это не память.
...
Рейтинг: 0 / 0
Какие из методов std::shared_ptr из нового стандарта потокобезопасны?
    #38030361
std::shared_ptr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
sherzod_Теперь представим что ресурс защищен простым мьютексом. Один поток захватит мьютекс и вызовет обновление кэш-линий других. Все остальные теперь просто заблокируются, будут ждать сигнала condition variable. Ни один из них (остальных) не вызовет обновление кэш линий. Захвативший поток отпускает мьютекс, вызывает обновление кэш линий изменяет condition variable. Ситуация повторяется сначала.
Хотите сказать, что обычный мьютекс сначала проверяет состояние атомарной операцией LOAD без барьера памяти, и только в случае успеха пытается сделать атомарный CAS с барьером, и по этому в большинстве случаев многие потоки обрубятся ещё на первом LOAD без барьера?

Но в любом случае, даже если мьютекс обрубиться то ему придется 3 раза синхронизовать кэш:
1. Остановить поток - затраты на переключение контекста (скорей всего тут больше одного барьера будет)
2. Захватить мьютекс когда он освободиться (барьер)
3. Возобновить поток - затраты на переключение контекста (скорей всего тут больше одного барьера будет)
...
Рейтинг: 0 / 0
Какие из методов std::shared_ptr из нового стандарта потокобезопасны?
    #38030370
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sherzod_Ваше утверждение что при длительной операции чтения boost::shared_mutex быстрее boost::mutex тоже безосновательно. Хотелось увидеть разбор причин, почему он должен быть быстрее.

Это же элементарно. Шаред лок это как следует из названия блокировка которую одновременно могут держать несколько потоков при чтении ресурса. Обратите внимание что допустим 100 потоков, при чтении за 10 сек каждый, суммарно выполнят чтение за те же 10 сек + тот постоянный оверхед про который вы тут все время говорите. Чем больше время удержания блокировки тем несущественнее вклад этого оверхеда (который кстати такой же как и у обычного мьютекса, о чем я многократно уже говорил)
А в точно такой же ситуации с уникальным локом - все потоки справятся за 100*10 секунд. Причем большую часть этого времени все эти потоки будут проводить в ожидании.

В этом и заключается назначение шаред мьютекса - избежать ожидания там где в нем смысла нет.

Ваше предположение о том что читаемая память будет в кэше не совсем верное. А если верное то это именно тот случай когда не следует применять shared_mutex. Мы ведь рассматриваем сценарий много читающих, мало или один записывающий. Без лишних объяснений думаю уже поймете что в таком сценарии нужно предотвратить кеширование читаемого/записываемого ресурса (volatile?). Зачем много раз читать то что не изменилось?
Мы каждый раз читаем потому что не знаем изменилось или нет.
Но в большинстве случаев данные не изменяются и остаются в кеше.
...
Рейтинг: 0 / 0
Какие из методов std::shared_ptr из нового стандарта потокобезопасны?
    #38030395
std::shared_ptr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly MoskovskyЭто я к чему.
Сели две группы людей: одни криворукие написали тормознутую реализацию shared_mutex, другие слепые не смогли там разглядеть что тормозит и не включили в стандарт потому что подумали что те криворукие самые умные и быстрее сделать нельзя.
А между тем была еще одна группа, которая в Windows Vista реализовала свой shared_mutex (под названием slim read/write lock ), который размером всего в один указатель, и работает быстрее чем boost::mutex. А там простой юзермод локфри - тот который якобы медленнее мьютекса.
1. А почему в boost/std не сделали элементарнейшую обертку над Win slim read/write lock и POSIX pthread_rwlock_t? Может оставили на следующий стандарт :)
2. slim read/write lock - это именно локфри или вейтфри? То что вы говорите, атомарный CAS захват счетчика - это вейтфри.
...
Рейтинг: 0 / 0
Какие из методов std::shared_ptr из нового стандарта потокобезопасны?
    #38030448
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
std::shared_ptr1. А почему в boost/std не сделали элементарнейшую обертку над Win slim read/write lock и POSIX pthread_rwlock_t? Может оставили на следующий стандарт :)
2. slim read/write lock - это именно локфри или вейтфри? То что вы говорите, атомарный CAS захват счетчика - это вейтфри.
1. Наверно когда делали это в бусте, в винде еще не было этого мьютекса (он есть начиная с Висты).
Почему не приняли в стандарт хотя бы концептуально, не знаю. При том что вполне часто встречаются кейсы для применения именно совместной блокировки (см. мой предыдущий ответ).

2. Ну если логически рассуждать то вряд ли объект реализующий концепцию блокировки можно назвать lock-free :) Ну и не wait-free тоже естественно. Под slim там подразумевалось что все реализуется атомарными операциями в usermode (а не в ядре). Хотя часто именно это имеют в виду когда говорят lock-free.
...
Рейтинг: 0 / 0
Какие из методов std::shared_ptr из нового стандарта потокобезопасны?
    #38030491
std::shared_ptr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly Moskovsky2. Ну если логически рассуждать то вряд ли объект реализующий концепцию блокировки можно назвать lock-free :) Ну и не wait-free тоже естественно. Под slim там подразумевалось что все реализуется атомарными операциями в usermode (а не в ядре). Хотя часто именно это имеют в виду когда говорят lock-free.
spin_lock тоже в юзер мод, но вот он как раз таки lock-based :)

А в shared_mutex именно та часть, которая shared, легко ложиться на wait-free, сделали один CAS инкремент счетчика и все.
Понятно, что в случае не успеха это будет обычный mutex, но это должно быть редко. По этому я тут вижу mutex-based + wait-free :)
...
Рейтинг: 0 / 0
Какие из методов std::shared_ptr из нового стандарта потокобезопасны?
    #38030509
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
std::shared_ptr,

Это все терминология, у которой нет устоявшегося смысла.
Например если взять вот эти определения то никак wait-free не выходит, т.к. нет никаких гарантий по времени на выполнение совместной блокировки.
...
Рейтинг: 0 / 0
Какие из методов std::shared_ptr из нового стандарта потокобезопасны?
    #38032050
std::shared_ptr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly Moskovskystd::shared_ptr,

Это все терминология, у которой нет устоявшегося смысла.
Например если взять вот эти определения то никак wait-free не выходит, т.к. нет никаких гарантий по времени на выполнение совместной блокировки.
Вот к этому я и веду:
авторlock-free ... поток, выполняющий операцию «сравнение с обменом» в цикле
В общем случае lock-free это в цикле две атомарные операции: LOAD и CAS. Прогресс получается только у одного ядра/потока, а остальные ядра/активные потоки выполняют в холостую 2 барьера памяти для каждой итерации LOAD+CAS. Итого при максимальной конкуренции в среднем на одну lock-free операцию будет приходиться 2*(число ядер) атомарных операций с барьером памяти.
В mutex'e же при неудаче поток не ломиться с двумя барьерами памяти в каждую итерацию, мешая остальным, а усыпляет поток на долгие микросекунды. Т.е. в mutex неудачливые потоки не мешают остальным.
...
Рейтинг: 0 / 0
25 сообщений из 33, страница 1 из 2
Форумы / C++ [игнор отключен] [закрыт для гостей] / Какие из методов std::shared_ptr из нового стандарта потокобезопасны?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]