Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Какую библиотеку посоветуете с потокобезопасными контейнерами?
|
|||
|---|---|---|---|
|
#18+
AlekseySQLЯ наоборот хочу поставить очень низкий приоритет своим потокам. Таким образом мне удастся запустить 4 дочерних потока (по количеству ядер) + основной поток для показа текущих сообщений из дочерних. Причем в этом случае основной поток не будет тормозить, потому что у него относительно дочерних потоков будет высокий приоритет и в тоже время ядро не будет простаивать между показами информации о ходе работы. Средствами ОС внутри потока понижай приоритет, по завершению возвращай как было. Не надо никаких менеджеров самодельных городить. Для виндовса GetCurrentThread() и SetThreadPriority() ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.03.2017, 09:12 |
|
||
|
Какую библиотеку посоветуете с потокобезопасными контейнерами?
|
|||
|---|---|---|---|
|
#18+
CEMbА если правильный, но opensource/freeware? Вы думаете за это не платят? Думаете, миллионы строк кода в ядре линукса написаны людьми которые не получают зарплату, просто как хобби? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.03.2017, 12:18 |
|
||
|
Какую библиотеку посоветуете с потокобезопасными контейнерами?
|
|||
|---|---|---|---|
|
#18+
Привет, я тот самый дядька, который гонит пургу на стендапах :-) Не мог пройти мимо NekZНапример, что не нужно математически доказывать корректность алгоритма -- нужно его обложить кучей грубых и нагрузочных тестов в продакшне. Типа "ну а мне-то чо, что доказано? Главное чтобы работало стабильно" Это довольно серьезный вопрос. Дело в том, что описание и доказательство работоспособности алгоритма обычно дается в независимом от языка реализации виде и поэтому - в предположении sequential consistent модели памяти. Думаю, SQ - это не то, что Вы хотели бы видеть у себя в программе. Работ, посвященных анализу конкурентных алгоритмов именно в модели памяти C++, немного (справедливости ради надо сказать, что их появляется все больше), и в основном они касаются простейших алгоритмов с двумя - тремя атомарными переменными. В случае алгоритмов с бОльшим числом взаимодействующих атомарных переменных анализ весьма затруднен. Инструментов для анализа довольно мало (я имею в виду открытых, open source) - кроме Thread Sanitizer, пожалуй, ничего и нет. Выхлоп, который дает TSan, довольно часто ставит меня в тупик... Есть ещё relacy Дмитрию Вьюкова, - пожалуй, наиболее продвинутый (по заложенной идее) на сегодня инструмент, жаль, что он не доведен до конца (хотелось бы инструментации кода в стиле санитайзеров). Вообще, я скажу крамольную вещь, - модель памяти C++ так, как она описана в стандарте, нежизнеспособна. Это набор аксиом, весьма слабо коррелирующих с реальным положением дел в hardware. Это мое сугубое ИМХО, но оно косвенно подтверждается, например, нежеланием разработчиков Linux переходить на модель памяти C++11 (как Вы помните, модель памяти C++11 также распространяется на C11), и это нежелание они (Linux developers) весьма неплохо аргументируют. NekZИли его подход к проектированию кода -- прямо на стэндапе показывал как подпирает свой код костылями (ещё и в виде макросов) Видимо, на одном из выступлений я забыл произнести сакральную фразу про то, что "lock-free алгоритмы настолько многословны, что не вмещаются на страницу презентации, поэтому здесь я нагадил применил макросы". Я тоже не любитель макромагии, подтверждением чему может быть исходный код libcds в первозданном, так сказать, виде. Ну и насчет костылей. Вы не поверите, пока не прочтете первоисточники, - половина lock-free кода - это именно костыли. Костыли для того, чтобы любое промежуточное состояние контейнера в процессе вставки/удаления элемента было персистентным. Поэтому я предпочитаю термин "трюки" ;-) Костыль - это кеши процессора. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.03.2017, 14:53 |
|
||
|
Какую библиотеку посоветуете с потокобезопасными контейнерами?
|
|||
|---|---|---|---|
|
#18+
khizmaxВообще, я скажу крамольную вещь, - модель памяти C++ так, как она описана в стандарте, нежизнеспособна. Это набор аксиом, весьма слабо коррелирующих с реальным положением дел в hardware. Это мое сугубое ИМХО, но оно косвенно подтверждается, например, нежеланием разработчиков Linux переходить на модель памяти C++11 (как Вы помните, модель памяти C++11 также распространяется на C11), и это нежелание они (Linux developers) весьма неплохо аргументируют. А есть ссылка на эти аргументы? И есть ли где-то кросс-процессорная модель памяти, которая лучше? Помимо memory_order_cunsume - кандидата на depricated, и не использования всех возможностей LL/SC - явных косяков не вижу. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.03.2017, 16:47 |
|
||
|
Какую библиотеку посоветуете с потокобезопасными контейнерами?
|
|||
|---|---|---|---|
|
#18+
Да, ссылки есть, например, одно из последних: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0124r1.html Вообще, у Paul McKenney много об этом. Но разговор идет не о том, что лучше/хуже, а о том, что они (модели памяти) различны. Ядро Линукса использует более "старую" модель (read/write barriers), которая возникла как раз из железа и зачастую более понятна в применении. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.03.2017, 17:40 |
|
||
|
Какую библиотеку посоветуете с потокобезопасными контейнерами?
|
|||
|---|---|---|---|
|
#18+
Dima TСредствами ОС внутри потока понижай приоритет, по завершению возвращай как было. Не надо никаких менеджеров самодельных городить. Для виндовса GetCurrentThread() и SetThreadPriority() Спасибо, обдумаю ваше предложение. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.03.2017, 21:54 |
|
||
|
Какую библиотеку посоветуете с потокобезопасными контейнерами?
|
|||
|---|---|---|---|
|
#18+
Anatoly MoskovskyВы думаете за это не платят? Думаете, миллионы строк кода в ядре линукса написаны людьми которые не получают зарплату, просто как хобби? я не знаю. Но если тут проскочило слово "зарплата", значит кто-то кому-то платит зарплату с доходов этого opensourse/freeware, вопрос в том, как этот кто-то этот доход получает. Я, конечно, новичок во всех этих коммерческих операциях, но мне кажется, что free vs pay отличается только тем, что в начале, "деньги" или "стулья", если сначала стулья (раздаём ядро бесплатно, делает сопровождение/консультации/доработки/да просто берём трубку телефона - за деньги), то есть вполне ощутимый шанс остаться без денег, особенно если ты никому не известный разработчик, даже если супер-гениальный. Если я не прав, то мне бы сильно хотелось узнать, как можно заработать на freeware одинокому девелоперу, я этой темой давно интересуюсь. khizmaxВообще, я скажу крамольную вещь, - модель памяти C++ так, как она описана в стандарте, нежизнеспособнаа можно небольшой экскурс по теме, как оно устроено, и почему оно плохо? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.03.2017, 05:33 |
|
||
|
Какую библиотеку посоветуете с потокобезопасными контейнерами?
|
|||
|---|---|---|---|
|
#18+
CEMbмне бы сильно хотелось узнать, как можно заработать на freeware одинокому девелоперу, я этой темой давно интересуюсь. Там заработки на конкретных внедрениях и консалтинге. Потом это зарабатывание имиджа как разработчика, т.е. резюме конкретными делами. Для заработка на том и другом необходимо время. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.03.2017, 07:45 |
|
||
|
Какую библиотеку посоветуете с потокобезопасными контейнерами?
|
|||
|---|---|---|---|
|
#18+
khizmaxПривет, я тот самый дядька, который гонит пургу на стендапах :-) Это хорошо, что ты к нам пришёл, я очень рад. Мне очень понравился твой доклад в первой трети, в связи со здоровым желанием выработать правильный подход к разработке многозадачного кода. Я целиком это поддерживаю, потому что уж очень много сейчас разрабов, желающих запустить 2000 потоков на любой чих... Остальное пока не смотрел, встал на моделях многопоточной/задачной обработки, -- тоже интересно! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.03.2017, 09:51 |
|
||
|
Какую библиотеку посоветуете с потокобезопасными контейнерами?
|
|||
|---|---|---|---|
|
#18+
Dima TСредствами ОС внутри потока понижай приоритет, по завершению возвращай как было. Не надо никаких менеджеров самодельных городить. Для виндовса GetCurrentThread() и SetThreadPriority() Я сижу под Linux и тут инет говорит, что приоритет меняется специальной структурой у объекта pthread_t. Такого объекта у меня нет, если все делать средствами qt. Как находясь в методе run изменить приоритет в Linux? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.03.2017, 10:03 |
|
||
|
Какую библиотеку посоветуете с потокобезопасными контейнерами?
|
|||
|---|---|---|---|
|
#18+
Не силен в линуксах. Гугл в помощь . Немного почитал, как понимаю там еще права замешаны, снизить вроде сможешь, а обратно повысить только с правами суперпользователя (root, sudo), т.е. если твоя прога будет без прав, то никаким способом не повысит обратно. Только поток завершать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.03.2017, 10:27 |
|
||
|
Какую библиотеку посоветуете с потокобезопасными контейнерами?
|
|||
|---|---|---|---|
|
#18+
Dima TТам заработки на конкретных внедрениях и консалтинге. Потом это зарабатывание имиджа как разработчика, т.е. резюме конкретными делами. Для заработка на том и другом необходимо время.покажите мне хоть одного такого разработчика. Шароварщиков я много видел, работающих по одному. Но вот ни одного фриварщика с деньгами не видел. Там должен быть адовый порог входа, чтобы себе такой имидж в одиночку сделать и не быть задавленным более крупными командами, тем более если это опенсорс. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.03.2017, 11:11 |
|
||
|
Какую библиотеку посоветуете с потокобезопасными контейнерами?
|
|||
|---|---|---|---|
|
#18+
CEMbа можно небольшой экскурс по теме, как оно устроено, и почему оно плохо? уфф, вкратце так и не опишешь... Это тема для хорошего застолья с пивом на весь вечер. Ниже - мое ИМХО. Я впервые услышал и увлекся lock-free структурами данных в 2006 году, то есть почти одновременно с началом дискуссии об atomic в C++11. Тогда (где-то 2008-2010 года) было несколько подходов к atomic и несколько жарких дискуссий в политкорректной форме, все документы есть на wg21 . Победил Hans Boehm и его подход. Так как в то время C++11 ещё не было, приходилось писать свои atomic-велосипеды и, соотвественно, изучать модели памяти различных архитектур (честно скажу - от тех времен в голове мало что осталось). Причем весьма полезной была инсайдерская инфа от разработчиков того или иного процессора с различных форумов. В стандарте модель памяти C++11 описана в терминах ячеек памяти, и memory order применяется тоже к ячейкам памяти. То есть если есть два различных адреса A и B, то, по стандарту, memory ordering, примененный к A и к B, никак не связаны. Отсюда вытекают некоторые подозрительные вещи: например, чтобы удовлетворить стандарту, предлагается вводить ненужные атомарные переменные с довольно тяжелыми операциями atomic fetch_add и memory_order_acq_rel ( вот разбор схемы Hazard Pointer в терминах C++11 memory model). Но реально memory order - это барьеры, на всех современных архитектурах они не применяются с конкретным адресам памяти, - они глобальны. На ассемблере барьер - это отдельная инструкция . Часто возражают - а вот Intel Itanium, у него load/store с явным указанием acq/rel-семантики в одной инструкции, то есть тут барьер явно привязан к конкретному адресу, что и постулирует стандарт. Но если почитать спеку Intel Itanium по его модели памяти, то там часто путаница - в одном месте cказано, что memory ordering применяется к адресу, в другом - про адреса вообще ни слова. И самое главное - по инфе от разработчиков Итаниума, внутри все эти acq/rel-полубарьеры для load/store - это обычный mfence, то есть полный барьер, не связанный с адресом! А теперь немного конспирологии ;-) Родителем memory model C++11 является, насколько я понимаю, Hans Boehm, - умный мужик ученый (любимое число - 42 ;), который на момент разработки стандарта работал... в лабораториях HP ! А кто такая HP? Это главный пропагандист архитектуры Itanium. А у Itanium load/store с явным указанием семантики acq/rel, - то, что мы сегодня видим в atomic load/store C++11. Что ещё мне не нравится в стандарте - то, что memory order явно связан с потоками (threads). Да, несомненно, модель памяти предназначена именно для multithread. Но попытка каким-то образом связать load.acq одного потока с store.rel другого - это запутывание читателя! Один поток никак не может влиять на видимость значений в другом; часто пишут "поток A записал в M значение 42, но поток B не увидит 42 в M, пока/если..." и т.д. Все это чушь полная! Вернее, это производное рассуждение от истинной проблемы. Видимостью мы управлять вообще не можем. У современных процессоров кеши когерентные, так что "A записал, а B не увидел" - с точки зрения кеша такого быть не может. Но вот порядок/order , в котором B увидит то, что записал A, может быть другим. И виноват в этом не кеш, а небольшой костыль в виде store buffer между каждым ядром процессора и L1 кешем. Порядком мы управлять можем - это называется memory fence/barrier. И это отдельная инструкция, а не довесок/флаг в виде memory order к atomic load/store. У меня большое подозрение, что C++11 memory model писалась исключительно для реализации spin lock. Но в конкурентных контейнерах применяются такие изощренные схемы, которым существующий memory ordering мал. Например, частый трюк при построении алгоритма конкурентного self-balanced дерева: операция поиска find() - неблокируемая, операции insert/erase - применяется fine grained locks на уровне узлов. То есть это схема single producer (только один поток может делать вращения) - multiple consumer (много потоков могут ходить по дереву, в том числе и по тем ветвям, которые в данный момент вращаются). При вращениях, особенно двойных, очень важен порядок, в котором указатели на узлы дерева (они, конечно же, atomic) модифицируются, иначе find()-потоки залезут не туда. Вопрос: какой тут должен быть memory ordering для чтения и записи node ptr?.. По сути, здесь достаточно store/store барьера во вращениях между каждым изменением указателя на узлы, то есть только в producer'е, чтобы задать порядок, в котором consumer'ы должны увидеть модифицируемые узлы поддерева. Как выразить это в C++11 memory model?.. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.03.2017, 11:42 |
|
||
|
Какую библиотеку посоветуете с потокобезопасными контейнерами?
|
|||
|---|---|---|---|
|
#18+
CEMbDima TТам заработки на конкретных внедрениях и консалтинге. Потом это зарабатывание имиджа как разработчика, т.е. резюме конкретными делами. Для заработка на том и другом необходимо время.покажите мне хоть одного такого разработчика. Nginx . Думаю у разработчика оплачиваемой работы хватает. Но таких единицы, кто в одиночку что-то массовое создал. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.03.2017, 12:26 |
|
||
|
Какую библиотеку посоветуете с потокобезопасными контейнерами?
|
|||
|---|---|---|---|
|
#18+
Сорри, мужик, не хотел чтобы что-то грубо прозвучало про твои выступления, просто прими ожидаемую реакцию/критику публики со стендапов. khizmaxУ современных процессоров кеши когерентные, так что "A записал, а B не увидел" - с точки зрения кеша такого быть не может. Но вот порядок/order , в котором B увидит то, что записал A, может быть другим. И виноват в этом не кеш, а небольшой костыль в виде store buffer между каждым ядром процессора и L1 кешем. А разве не было заявлено много раз про то, что разные потоки, могут выполняться на разных процессорах , что будет триггерить перебрасывание кэшей между процессорами, что является серьёзным оверкиллом? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.03.2017, 13:07 |
|
||
|
Какую библиотеку посоветуете с потокобезопасными контейнерами?
|
|||
|---|---|---|---|
|
#18+
NekZ, Несомненно, было заявлено, но при этом когерентность кешей разных процессоров никто не отменяет. Именно поэтому в многопроцессорных системах так тормозит обращение к данным "чужого" процессора. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.03.2017, 13:22 |
|
||
|
Какую библиотеку посоветуете с потокобезопасными контейнерами?
|
|||
|---|---|---|---|
|
#18+
khizmaxNekZ, Несомненно, было заявлено, но при этом когерентность кешей разных процессоров никто не отменяет. Именно поэтому в многопроцессорных системах так тормозит обращение к данным "чужого" процессора. приветствую как-то довольно печальненько однако простой интерлок переменной у меня на i7 упирается в 40 млн операц./c, с 150 млн./с на 1-м ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.03.2017, 13:55 |
|
||
|
Какую библиотеку посоветуете с потокобезопасными контейнерами?
|
|||
|---|---|---|---|
|
#18+
khizmax , Но помимо привязки к процессору, модель памяти должна была быть привязана к компилятору, поэтому memory_order одновременно барьеры и для процессора и для компилятора. Здесь есть как минимум 3 преимущества привязки барьеров к операциям: 1. Не все барьеры подходят для всех операций, для store (не подходят consume, acquire, acq_rel), а для load (не подходят release, acq_rel), и компилятор выдаёт compile-time ошибку. Этого он не может сделать для барьеров оторванных от операций. 2. Для компилятора, помимо изменения порядка - это ещё и управление spilling/filling всеми, в том числе неатомарными переменными. 3. Если процессоры делятся weak и strong модели памяти, то компилятор изначально всегда weak - и это даёт ему огромные возможности для оптимизаций. Барьеры не привязанные к операциям закрывают для переупорядочивания целые направления для всех операций, а не только для некоторых. Насчет оптимизаций компилятора, допустим, у меня есть код (здесь Store-Load последовательность, которая без seq_cst могла бы переупорядочиваться): Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. Я хочу дать возможность компилятору двигать c.store() в любую сторону: до a.store() или после b.load() - это даст компилятору больше манёвров для оптимизации. И в данном случае компилятор это сделать может. Теперь перепишу этот код, как если бы мы делали с барьерами памяти отделенными от операций (для корректности оставлю переменные атомарными но всегда в них буду использовать самую слабую relaxed): Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. В какой бы из 2-ух позиций я не вставил atomic_thread_fence( memory_order_seq_cst ) - это всегда закрывает как минимум одно направление для оптимизации. Компилятор не может понять к какой операции относится atomic_thread_fence-барьер, и какую операцию можно перемещать свободно, а какую нет. khizmaxВ стандарте модель памяти C++11 описана в терминах ячеек памяти, и memory order применяется тоже к ячейкам памяти. То есть [b]если есть два различных адреса A и B, то, по стандарту, memory ordering, примененный к A и к B, никак не связаны . Отсюда вытекают некоторые подозрительные вещи: например, чтобы удовлетворить стандарту, предлагается вводить ненужные атомарные переменные с довольно тяжелыми операциями atomic fetch_add и memory_order_acq_rel А что имеется ввиду под выделенным? Например, если мы применим seq_cst к store(A) и последующем load(B), то гарантировано будет предотвращено Store-Load-переупорядочивание только для этих двух операций, и ни для каких больше. Следующий код (между c.store() и b.load() может не генерироваться mfence, про исключения вы наверное знаете): Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. На всех типичных компиляторах x86_64 может быть пере-упорядочен так: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. c.store(rel); b.load(seq); могут быть переупорядочены в b.load(seq); c.store(rel); Мало того, на других компиляторах или процессорах могут быть и другие изменения порядка: a.storeA(seq_cst); c.load(acq_rel); может быть переупорядочен в c.load(acq_rel); a.store(seq_cst); ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.03.2017, 15:50 |
|
||
|
Какую библиотеку посоветуете с потокобезопасными контейнерами?
|
|||
|---|---|---|---|
|
#18+
Вася Уткин, я ждал этого вопроса, про оптимизации компилятора ;-) Вы уже все сами ответили - да, барьеры также являются и барьерами компилятора. Полагаю, C++11 memory model для компиляторов был головной болью, ибо запрещал практически все оптимизации (речь, конечно, об atomic), - все они рассчитаны на один поток. Например, GCC, объявив GCC-4.8 "C++11 ready", только к GCC-6 восстановил большую часть оптимизаций (это мое наблюдение и найденные обмолвки/слухи/тесты в инете, пруфа не дам). Но почему они (барьеры) должны быть обязательно прикреплены к atomic load/store/RMW?.. load(acquire) - это load x membar LoadLoad | LoadStore store( release ) - это membar LoadStore | StoreStore store x Вот вам явные (полу)барьеры с relaxed load/store. Они же - барьеры компилятора (они же - ассемблер Sparc; пожалуй, у Sparc была наиболее прямая memory model, без излишеств, но которая позволяла всё). Это та модель, которая применялась до C++11, которая применяется сейчас в ядре Linux и которая прямо вытекает из железа. И здесь барьеры не привязаны к ячейкам памяти, которые читаются/пишутся. Это просто явное указание упорядочения load/store. Именно это я и "имел в виду под выделенным" - барьер не привязан явно к адресу. Если вы внимательно прочтете ту ссылку, которую я давал, не весь документ, а часть про Hazard Pointer, - увидите: там ради удовлетворения стандарта (которого на момент написания ещё не было, но он активно обсуждался) вводится ненужная для HP атомарная переменная, через которую синхронизируются потоки с помощью RMW. И все потому, что в HP atomic.load(A, acquire) и тут же atomic.store(B, release) - два разных адреса, а два разных адреса по C++11 не синхронизируются. В общем, чем больше я работаю с atomic/memory ordering, - тем больше у меня вопросов. Maybe, это потому, что в свое время я начитался запрещенной литературы мануалов по различным архитектурам (кстати, могу сказать, - по большей части многотомное и бесполезное чтиво, только запутывает, начинаешь с подозрением относится даже к регистровым операциям). Мне все больше кажется, что C++11 memory model - это лишь первая итерация, ещё далекая до идеала. И я рад, что нашлись линуксоиды-ядерщики, которые задают комитету похожие вопросы, - значит, дискуссия продолжится и решение будет найдено. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.03.2017, 17:14 |
|
||
|
Какую библиотеку посоветуете с потокобезопасными контейнерами?
|
|||
|---|---|---|---|
|
#18+
khizmaxПолагаю, C++11 memory model для компиляторов был головной болью, ибо запрещал практически все оптимизации (речь, конечно, об atomic) , - все они рассчитаны на один поток. Например, GCC, объявив GCC-4.8 "C++11 ready", только к GCC-6 восстановил большую часть оптимизаций (это мое наблюдение и найденные обмолвки/слухи/тесты в инете, пруфа не дам). Строго говоря, C++11 memory model не запрещает все оптимизации, мало того она запрещает оптимизаций значительно меньше, чем запрещают атомарные операции применяемые в ядре Linux. А то, что конкретно старые версии GCC 4.8 - 6.0 не умели оптимизировать C++11 memory model - это проблема недоделанного компилятора. А в clang или icc с этим все заметно лучше. khizmax вводится ненужная для HP атомарная переменная, через которую синхронизируются потоки с помощью RMW. И все потому, что в HP atomic.load(A, acquire) и тут же atomic.store(B, release) - два разных адреса, а два разных адреса по C++11 не синхронизируются. Не понял про какое именно место в Hazard Pointer вы говорите. Но если покажите конкретную строчку(и) кода в PDF или у вас в libcds - смогу что-либо конкретное ответить. Вот в таком коде стандарт C++11 может переместить c.store() как до a.store(), так и после b.load(). Мало того, даже скомпилированный код может быть переупорядочен процессором подобным образом: c.store(relaxed) <-> b.load(seq_cst) на x86_64: https://godbolt.org/g/Tft2vw a.store(seq_cst) <-> c.store(relaxed) на PowerPC: https://godbolt.org/g/oZGB4x Вы, например, как бы переписали данный код с барьерами не привязанными к операциям? Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.03.2017, 18:37 |
|
||
|
Какую библиотеку посоветуете с потокобезопасными контейнерами?
|
|||
|---|---|---|---|
|
#18+
Поправил: Вася Уткин a.store(seq_cst) <-> c.load(relaxed) c.store(relaxed) на PowerPC: https://godbolt.org/g/oZGB4x ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.03.2017, 20:36 |
|
||
|
Какую библиотеку посоветуете с потокобезопасными контейнерами?
|
|||
|---|---|---|---|
|
#18+
NekZAlekseySQL, Смотрели в boost::lockfree? Посмотрел, и разочаровался: у очереди один метод push, который Not Thread-safe ( http://www.boost.org/doc/libs/1_63_0/doc/html/boost/lockfree/queue.html). У меня все наоборот: много писателей (дочерние потоки) и один читатель (основной поток). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.03.2017, 13:24 |
|
||
|
Какую библиотеку посоветуете с потокобезопасными контейнерами?
|
|||
|---|---|---|---|
|
#18+
AlekseySQLПосмотрел, и разочаровался: у очереди один метод push, который Not Thread-safe ( http://www.boost.org/doc/libs/1_63_0/doc/html/boost/lockfree/queue.html). У меня все наоборот: много писателей (дочерние потоки) и один читатель (основной поток). Странно, а по ссылке, что вы привели, написано, что он Thread-safe Вообще было бы странно если бы операции модификации очереди, которая по дизайну потокобезопасна, вдруг оказались недопустимы в потоках ))) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.03.2017, 13:35 |
|
||
|
Какую библиотеку посоветуете с потокобезопасными контейнерами?
|
|||
|---|---|---|---|
|
#18+
Вася УткинНасчет оптимизаций компилятора, допустим, у меня есть код (здесь Store-Load последовательность, которая без seq_cst могла бы переупорядочиваться): Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. Я хочу дать возможность компилятору двигать c.store() в любую сторону: до a.store() или после b.load() - это даст компилятору больше манёвров для оптимизации. И в данном случае компилятор это сделать может. Странно, я всегда думал что через load/store совмещенный с seq_cst компилятору нельзя двигать операции в обе стороны (так же как и через release/acquire в одну сторону), иначе например мьютекс не будет работать. Т.е. мое понимание было что load/store эквивалентно неатомарным операциям + отдельный барьер. И весь спор про разницу моделей С++ и линукса ни о чем кроме синтаксиса. Нет? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.03.2017, 13:41 |
|
||
|
Какую библиотеку посоветуете с потокобезопасными контейнерами?
|
|||
|---|---|---|---|
|
#18+
Anatoly MoskovskyВася УткинНасчет оптимизаций компилятора, допустим, у меня есть код (здесь Store-Load последовательность, которая без seq_cst могла бы переупорядочиваться): Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. Я хочу дать возможность компилятору двигать c.store() в любую сторону: до a.store() или после b.load() - это даст компилятору больше манёвров для оптимизации. И в данном случае компилятор это сделать может. Странно, я всегда думал что [b]через load/store совмещенный с seq_cst компилятору нельзя двигать операции в обе стороны (так же как и через release/acquire в одну сторону), иначе например мьютекс не будет работать. Т.е. мое понимание было что load/store эквивалентно неатомарным операциям + отдельный барьер. И весь спор про разницу моделей С++ и линукса ни о чем кроме синтаксиса. Нет? Выделенное не верно, в стандарте написано по другому, но запутанно, и вы его читали, а раз не поняли - поэтому зайду с другой стороны. Я покажу во что компилятор компилирует load/store совмещенный с seq_cst, и покажу какие переупорядочивания он оставляет процессору. А раз компилятор оставляет возможность таких переупорядочиваний процессору, значит и сам компилятор может делать эти же переупорядочивания . Я покажу, как в этом коде процессор может переместить c.sotre(relaxed) как до a.store(seq_cst), так и после b.load(seq_cst): 1. Посмотрим что возможно на уровне asm-инструкций : https://en.wikipedia.org/wiki/Memory_ordering#In_symmetric_multiprocessing_.28SMP.29_microprocessor_systems * x86_64 - strong memory model - allows Store-Load reordering (if there is no MFENCE) - правильно? * PowerPC - weak memory model - allows Store-Store reordering (if there is no SYNC) - правильно? 2. Теперь посмотрим во что GCC компилирует "load/store совмещенный с seq_cst": * x86_64 - может переупорядочить Store-Load т.к. между ними нет MFENCE: * PowerPC - может переупорядочить Store-Store т.к. между ними нет sync: В итоге получается, что один и тот же код скомпилированный под разные платформы может иметь одно из двух переупорядочиваний: c.store(relaxed) <-> b.load(seq_cst) на x86_64: https://godbolt.org/g/Tft2vw a.store(seq_cst) <-> c.store(relaxed) на PowerPC: https://godbolt.org/g/BTQBr8 Мало того, теоретически, но обычно не используют в компиляторах, семантика seq_cst может иметь 4 реализации на x86_64: 1. LOAD (without fence) and STORE + MFENCE 2. LOAD (without fence) and LOCK XCHG 3. MFENCE + LOAD and STORE (without fence) 4. LOCK XADD ( 0 ) and STORE (without fence) Где 1 - это в GCC, 2 - это Clang & MSVC - по сути одно и тоже, очищает Store-Buffer после STORE А 3 и 4 - не используют в компиляторах - очищают Store-Buffer перед LOAD Так вот если бы некий компилятор использовал 3 и 4 реализацию seq_cst на x86_64, то была бы возможность переупорядочивания: a.store(seq_cst) <--> c.load(relaxed) Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.03.2017, 14:43 |
|
||
|
|

start [/forum/topic.php?fid=57&msg=39422115&tid=2018235]: |
0ms |
get settings: |
8ms |
get forum list: |
12ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
226ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
50ms |
get tp. blocked users: |
1ms |
| others: | 11ms |
| total: | 325ms |

| 0 / 0 |
