Здравствуйте, Коваленко Дмитрий, Вы писали:
КД>Возник только один вопрос — а что это за "указатели опасности" (266-274)?
"hazard pointers" в английском издании.
Указатели, данные по которым достижимы из нескольких потоков. (В контексте lock-free структур данных и проблемы удаления элементов контейнераа.)
Здравствуйте, Chorkov, Вы писали:
C>Здравствуйте, Коваленко Дмитрий, Вы писали:
КД>>Возник только один вопрос — а что это за "указатели опасности" (266-274)?
C>"hazard pointers" в английском издании. C>Указатели, данные по которым достижимы из нескольких потоков. (В контексте lock-free структур данных и проблемы удаления элементов контейнераа.)
Ага. Оказывается тут после оплаты электронный вариант книги закидывают. Сейчас ознакомлюсь.
Понапридумывают терминов
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
КД>Возник только один вопрос — а что это за "указатели опасности" (266-274)?
В переводе 1-го издания на 277 странице эти указатели опасности упомянуты.
На мой взгляд, тут надо спрашивать переводчика об этом термине. К сожалению, предисловия переводчика в книжке нет.
Написано вот что:
Темин "указатели опасности" относится к технике, предложенной Maged Michael. Они называются так потому, что удаление узла, на который все еще могут ссылаться другие потоки, опасное предприятие.
...
Основная идея состоит в том, что поток, собирающийся получить доступ к объекту, который другой поток может захотеть удалить, сначала устанавливает указатель опасности, ссылающийся на этот объект, информируя тем самым другой поток, что удалять этот объект действительно опасно. После того, как объект перестает быть нужным, указатель опасности очищается.
...
Собираясь удалить объект, поток должен сначала проверить все указатели опасности всех потоков.
...
Поток должен периодически просматривать указатели опасности, чтобы выяснить, можно ли удалять объект.
Если все они пустые, то объект можно безопасно удалить.
...
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Здравствуйте, Chorkov, Вы писали:
КД>>Возник только один вопрос — а что это за "указатели опасности" (266-274)?
C>"hazard pointers" в английском издании. C>Указатели, данные по которым достижимы из нескольких потоков. (В контексте lock-free структур данных и проблемы удаления элементов контейнераа.)
А как перевод? Кроме "указателей опасности" еще косяки есть? Стоит брать наше издание или лучше оригинал? Млин, на Амазоне нет kindle версии
_____________________
С уважением,
Stanislav V. Zudin
Здравствуйте, Коваленко Дмитрий, Вы писали:
КД>Возник только один вопрос — а что это за "указатели опасности" (266-274)?
Распечатал и прочитал эту главу. Краткий пересказ:
Давайте возьмем хрень и заставим её работать. Хрень работает плохо, но мы можем её улучшить. Потом её раз улучшить. Все равно хреново. Кстати, на эту хрень у IBM есть патент, так что вы поосторожнее с этой хренью.
От себя добавлю, в этой хрени есть выделение памяти при регистрации в списке отложенного удаления. Ну вы меня поняли...
Для дальнейшего обсуждения этой хрени надо здесь привести её исходный код — за это ко мне претензии со стороны издательства не выкатят?
UPD. Походу, не могу — там в начале про это написано. Там же написано, что они ни за что не отвечают
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
memory_order_acquire — перегружает кэш ранее загруженных данных потока.
И все, Карл.
А, на да. memory_order_consume — это хитровывернутый memory_order_acquire, перегружающий (в кэше потока) только то, что связано с конкретной переменной. Я так понимаю — это способ нагнуть компилятор на построении дерева зависимостей.
---
В 5.3.6, он запутался с нумерацией меток
В примере из 5.3.4 (листинг 5.11) возникнет жопа, если populate_queue встанет на паузу — count.fetch_sub довызывается до положительного результата и все навернется. Мог бы и предупредить.
---
Без пятой главы не получилось дочитать седьмую
---
Вообще интересная книженция. Печатный вариант пока еще не доехал
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
КД>Я башку сломал, пока понял, что на самом деле объясняется вполне простая и понятная вещь.
КД>memory_order_release — сбрасывает буфер отложенных записей/вычислений потока.
КД>memory_order_acquire — перегружает кэш ранее загруженных данных потока.
КД>И все, Карл.
вот поэтому книжки и пишут что бы люди думали что они все поняли
на самом деле все не так
читайте другую книгу
Здравствуйте, Коваленко Дмитрий, Вы писали:
КД>Я башку сломал, пока понял, что на самом деле объясняется вполне простая и понятная вещь.
КД>memory_order_release — сбрасывает буфер отложенных записей/вычислений потока.
КД>memory_order_acquire — перегружает кэш ранее загруженных данных потока.
Я при всем при том, я встречал немало людей, которые вполне искренне считали, что достаточно написать volatile, и все с порядком доступа к памяти станет хорошо.
КД>А, на да. memory_order_consume — это хитровывернутый memory_order_acquire, перегружающий (в кэше потока) только то, что связано с конкретной переменной. Я так понимаю — это способ нагнуть компилятор на построении дерева зависимостей.
Нет. Есть то поведение, на которые рассчитывает программист, и есть то, что может сделать процессор. Компилятору проще всего было бы всегда делать full barrier, но это и самый неэффективных способ. Поэтому если процессор умеет что-то менее радикальное, компилятору не помешало бы знать, что человек имел ввиду. А поскольку стандарт рассчитан на максимально широкий ассортимент процессоров, включая те, которые, возможно, появятся лишь в будующем, то и способы описания того, что человек имел ввиду, предоставляются максимально широкие.
Здравствуйте, Pzz, Вы писали:
КД>>Я башку сломал, пока понял, что на самом деле объясняется вполне простая и понятная вещь.
КД>>memory_order_release — сбрасывает буфер отложенных записей/вычислений потока.
КД>>memory_order_acquire — перегружает кэш ранее загруженных данных потока.
Pzz>Я при всем при том, я встречал немало людей, которые вполне искренне считали, что достаточно написать volatile, и все с порядком доступа к памяти станет хорошо.
Предлагаю обсуждать не людей, а книгу.
Лично я, с точки зрения тестирования этой книги, представлял собой идеальный вариант, поскольку ничего внятного на эту тему (поддержка многопоточного кода в последних плюсах) до этого не читал.
Про многопоточный код у меня есть некоторое представления.
КД>>А, на да. memory_order_consume — это хитровывернутый memory_order_acquire, перегружающий (в кэше потока) только то, что связано с конкретной переменной. Я так понимаю — это способ нагнуть компилятор на построении дерева зависимостей.
Pzz>Нет. Есть то поведение, на которые рассчитывает программист, и есть то, что может сделать процессор. Компилятору проще всего было бы всегда делать full barrier, но это и самый неэффективных способ. Поэтому если процессор умеет что-то менее радикальное, компилятору не помешало бы знать, что человек имел ввиду.
Я это (переупорядочивание инструкций компилятором) попытался обозначить в "сбрасывает буфер отложенных записей/вычислений потока"
Не стал писать про memory_order_relax, который это и разрешает в явном виде.
---
Так вот.
Автору бы не стоило внятно обозначить, что:
— компилятор может переупорядочивать инструкции.
— memory_order нужен для контроля/настройки этого переупорядочивания. И это означает, что компилятор начал тесно взаимодействовать с конструкциями из пространства std.
— std::atomic и его методы не перестанут быть атомарными при указании различных memory_order.
Я тут заглянул в STL VS2019 (default настройки консольного проекта для Widnows) — похоже оно кладет болт на memory_order
// now make new_node the new head, but if the head
// is no longer what's stored in new_node->next
// (some other thread must have inserted a node just now)
// then put that new head into new_node->next and try againwhile(!head.compare_exchange_weak(new_node->next, new_node,
std::memory_order_release,
std::memory_order_relaxed))
; // the body of the loop is empty
// Note: the above use is not thread-safe in at least
// GCC prior to 4.8.3 (bug 60272), clang prior to 2014-05-05 (bug 18899)
// MSVC prior to 2014-03-17 (bug 819819). The following is a workaround:
// node<T>* old_head = head.load(std::memory_order_relaxed);
// do {
// new_node->next = old_head;
// } while(!head.compare_exchange_weak(old_head, new_node,
// std::memory_order_release,
// std::memory_order_relaxed));
И это частично дает ответ на вопрос, который я хотел здесь задать с самого начала — "кто нибудь уже начал использовать эти плюсовые штуки для многопоточности в промышленном коде для дикой природы?".
---
Все, пойду дочитывать седьмую главу, в которой автор натягивает сову на глобус тюнит memory_order в безблокировочном коде
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
КД>>Я башку сломал, пока понял, что на самом деле объясняется вполне простая и понятная вещь.
КД>>memory_order_release — сбрасывает буфер отложенных записей/вычислений потока.
КД>>memory_order_acquire — перегружает кэш ранее загруженных данных потока.
КД>>И все, Карл.
R>вот поэтому книжки и пишут что бы люди думали что они все поняли R>на самом деле все не так
И это говорит о качестве этой книги.
R>читайте другую книгу
Теперь осталось осознать — как такое вообще возможно?
И то "понимание", которое у меня появилось после книги, похоже только мешает.
------
UPD. Не. Думаю, я понял все правильно. Но не до конца. memory_order_release "выгружает" накопленные результаты деятельности потока. Но делает это асинхронно (считай — в еще одном фоновом потоке). Да?
Если я опять туплю — готов выслушать разумное объяснение.
------
UPD2. И кстати практический вопрос — на Intel срабатывание этого ассерта можно воспроизвести?
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Здравствуйте, Коваленко Дмитрий, Вы писали:
КД>Я тут заглянул в STL VS2019 (default настройки консольного проекта для Widnows) — похоже оно кладет болт на memory_order
x86, полный своих хитрых аппаратных автоматизмов, позволяет изрядные вольности на эту тему.
КД>И это частично дает ответ на вопрос, который я хотел здесь задать с самого начала — "кто нибудь уже начал использовать эти плюсовые штуки для многопоточности в промышленном коде для дикой природы?".
Промышленность использует новомодные штучки, когда они уже перестают быть новомодными. И правильно делает, между прочим.