Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Lock-free очередь
|
|||
|---|---|---|---|
|
#18+
mikronSOFT FOR YOU_head и _tail это не указатели на узлы, это указатели + счётчики Сделаны счётчики для обхода ABA, но с другой стороны в C# не бывает ABA Я не понимаю проблeмы ABA в контексте конкретной задачи. По моему понял: у вас при Enqueue освобождается Node, который ещё в использовании другим потоком. Next := PNode(Head.Value).Next; Здесь вы читаете из узла который уже может быть потерян / затёрт / переписан. Да, в шарпе такое невозможно. А ваши умные указатели со счётчиком проблему освобождения ИМХО не решают. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.11.2017, 12:43 |
|
||
|
Lock-free очередь
|
|||
|---|---|---|---|
|
#18+
mikron, Если без счётчика, то атомик считается успешным, если указатель на старте и указатель в конце совпадают. Проблема в том, что в промежутке поток исчерпает лимит времени, и пока он ожидает, из вершины кто-то извлечёт указатель, а потом вернёт, но уже совершенно с другим содержимым. С точки зрения логики первый поток должен уйти на следующую итерацию цикла, с точки зрения атомика - он отработает, приведя контейнер в некорректное состояние В традиционных менеджерах памяти, если ты удалил кусок памяти, потом при выделении ты можешь получить память с тем же указателем. В GC менеджерах такого не происходит. А а традиционных принято хранить не только указатель, но и условно говоря номер версии. И CAS происходит не над указателем, а сразу над парой указатель-счётчик. И да, при Dequeue мы можем рассматривать Node, который уже удалён, и в котором Next может содержать мусор. На практике там содержится указатель на ранее удалённую память или же nil. НО. Я так и не придумал ситуации, где это может привести к ошибке. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.11.2017, 13:26 |
|
||
|
Lock-free очередь
|
|||
|---|---|---|---|
|
#18+
SOFT FOR YOUmikron, Если без счётчика, то атомик считается успешным, если указатель на старте и указатель в конце совпадают. Проблема в том, что в промежутке поток исчерпает лимит времени, и пока он ожидает, из вершины кто-то извлечёт указатель, а потом вернёт, но уже совершенно с другим содержимым. IMHO С counter вы защищаете указатель головы/хвоста а проблема начинается уже тогда, когда вы читаете из освобождённой памяти, т.е. сразу после освобождения памяти. Ваши счётчики что мёртвому припарка - поздно. Когда вы решите проблему с овобождением используемой/читаемой памяти, то и счётчики вам не понадобятся. SOFT FOR YOUВ традиционных менеджерах памяти, если ты удалил кусок памяти, потом при выделении ты можешь получить память с тем же указателем. В GC менеджерах такого не происходит. скажем так: с GC это маловероятно, но теоретически возможно. SOFT FOR YOUИ да, при Dequeue мы можем рассматривать Node, который уже удалён, и в котором Next может содержать мусор. На практике там содержится указатель на ранее удалённую память или же nil. НО. Я так и не придумал ситуации, где это может привести к ошибке. У вас нет гарантии что между удалением и в первом потоке и чтением Next := PNode(Head.Value).Next; во втором, первый или третий не затребуют память и не перепишут значения. К тому же часто Allocate вернёт тот-же участок при том же размере запрашиваемой памяти. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.11.2017, 14:40 |
|
||
|
Lock-free очередь
|
|||
|---|---|---|---|
|
#18+
mikronDima T, Интересно, кто их тогда пишет, инопланетяне? Тот кто понимает как их писать. Лично я понимаю что есть куча нюансов, поэтому даже не буду пытаться написать, возьму готовое. Простой заменой мутекса на InterlockedExchange тут тоже не особо ускоришь, т.к. если несколько потоков меняют один и тот же кусок в памяти это уже тормоз из-за синхронизации кэшей ядер проца, надо более сложное решение. И самое главное очень сложно доказать что твое решение рабочее, т.к. твои тесты могут пройти, а где-то возникнет ситуация когда этот код отработает неправильно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.11.2017, 18:02 |
|
||
|
Lock-free очередь
|
|||
|---|---|---|---|
|
#18+
SOFT FOR YOUmayton, Нет, а зачем профилировать? Сейчас же вопрос в корректности, а не в производительности Тогда зачем ты это все затеял? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.11.2017, 18:09 |
|
||
|
Lock-free очередь
|
|||
|---|---|---|---|
|
#18+
mikron, Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. Возможен случай, когда узел уже удалили и в Next лежит мусор Но тогда FHead будет уже не такой как при чтении, и FHead.AtomicCmpExchange(Next, Head) не сработает, а значит, уйдёт на следующую итерацию ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.11.2017, 18:22 |
|
||
|
Lock-free очередь
|
|||
|---|---|---|---|
|
#18+
SOFT FOR YOUmikron, Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. Возможен случай, когда узел уже удалили и в Next лежит мусор Но тогда FHead будет уже не такой как при чтении, и FHead.AtomicCmpExchange(Next, Head) не сработает, а значит, уйдёт на следующую итерацию Да, верно. Но TSyncPointer.SetValue счётчик не меняет. 0:Первоначально: очередь содержит один елемент. 1:T1: Dequeue: Читает голову / хвост 2:T2: Dequeue: Читает голову / хвост 3:T2: Удаляет елемент, изменяет хвост (До обновления головы) 4:T3: Enqueue: обновлает хвост и голову 5:Т2: не обновляет голову освобождает память 6:Т3: Dequeue: Читает голову / хвост, Удаляет елемент, изменяет хвост (До обновления головы) 7:T2: Enqueue: Получает память ту же что он осводил в начале, и ту же что видит Т1. т.к. хвост пустой, обновлает хвост, прописывает голову 8:Т3: не обновляет голову освобождает память. 9:Т3: Enqueue: новый елемент, обновлает хвост и склеивает с предидущим. 10:Т1: смотрит на нод, видит ссылку и успешно!! меняет голову, т.к. счётчик никогда не менялся и тот же елемент в голове. Так пойдёт? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.11.2017, 19:05 |
|
||
|
Lock-free очередь
|
|||
|---|---|---|---|
|
#18+
Dima T Лично я понимаю что есть куча нюансов, поэтому даже не буду пытаться написать, возьму готовое. Кто сдаётся без боя, не имеет шансов выиграть. Wer nicht wagt kann nicht gewinnen. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.11.2017, 19:15 |
|
||
|
Lock-free очередь
|
|||
|---|---|---|---|
|
#18+
SOFT FOR YOU, Попробуй в TSyncPointer.SetValue увеличивать счётчик. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.11.2017, 19:18 |
|
||
|
Lock-free очередь
|
|||
|---|---|---|---|
|
#18+
mikronDima T Лично я понимаю что есть куча нюансов, поэтому даже не буду пытаться написать, возьму готовое. Кто сдаётся без боя, не имеет шансов выиграть. Wer nicht wagt kann nicht gewinnen. Умный в гору не пойдет, умный гору обойдет (с) Надо задачи шире ставить, т.е. не просто создать Lock-free очередь, т.к. сам факт наличия очереди это решение в синхронном стиле, т.е. тут попытка улучшить плохое решение вместо поиска хорошего. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.11.2017, 19:59 |
|
||
|
Lock-free очередь
|
|||
|---|---|---|---|
|
#18+
Dima TУмный в гору не пойдет, умный гору обойдет (с) Тоже верно, но некоторых тянет в горы. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.11.2017, 20:09 |
|
||
|
Lock-free очередь
|
|||
|---|---|---|---|
|
#18+
Dima T, У всех предел пытливости и развития разный. Если человек не развивается - он умирает ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.11.2017, 22:16 |
|
||
|
Lock-free очередь
|
|||
|---|---|---|---|
|
#18+
mikronSOFT FOR YOUmikron, Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. Возможен случай, когда узел уже удалили и в Next лежит мусор Но тогда FHead будет уже не такой как при чтении, и FHead.AtomicCmpExchange(Next, Head) не сработает, а значит, уйдёт на следующую итерацию Да, верно. Но TSyncPointer.SetValue счётчик не меняет. 0:Первоначально: очередь содержит один елемент. 1:T1: Dequeue: Читает голову / хвост 2:T2: Dequeue: Читает голову / хвост 3:T2: Удаляет елемент, изменяет хвост (До обновления головы) 4:T3: Enqueue: обновлает хвост и голову 5:Т2: не обновляет голову освобождает память 6:Т3: Dequeue: Читает голову / хвост, Удаляет елемент, изменяет хвост (До обновления головы) 7:T2: Enqueue: Получает память ту же что он осводил в начале, и ту же что видит Т1. т.к. хвост пустой, обновлает хвост, прописывает голову 8:Т3: не обновляет голову освобождает память. 9:Т3: Enqueue: новый елемент, обновлает хвост и склеивает с предидущим. 10:Т1: смотрит на нод, видит ссылку и успешно!! меняет голову, т.к. счётчик никогда не менялся и тот же елемент в голове. Так пойдёт? Великолепный сценарий Благодарю! Заменил инициализацию FHead.Value на FHead.Full() Эта реализация берёт старый счётчик и в новом значении счётчик инкрементируется Правда делаю это обычным чтением и обычной записью, без атомиков Проблема осталась Я думаю, нужно взглянуть на вариант сравнения Next с nil (мусор) и Head.Value/Tail.Value ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.11.2017, 00:08 |
|
||
|
Lock-free очередь
|
|||
|---|---|---|---|
|
#18+
SOFT FOR YOUDima T, У всех предел пытливости и развития разный. Если человек не развивается - он умирает Главное чтобы пытливость не превращалась в манию велосипедостроения. Ты по ссылке 20944940 сходил? Там автор не поленился, собрал много материала по lock-free алгоритмам. В т.ч. про очереди . ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.11.2017, 11:12 |
|
||
|
Lock-free очередь
|
|||
|---|---|---|---|
|
#18+
Dima T, Да, я подробно изучил его материалы С его реализации очереди всё и пошло. Но у него Хазард Поинтер, а у меня фри лист Хазард плох тем, что ты должен контролировать создание и удаление всех потоков А у меня более универсальный подход, не зависимо от того, где и на каком языке создан поток Есть стек. Осталось очередь и хеш ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.11.2017, 12:01 |
|
||
|
Lock-free очередь
|
|||
|---|---|---|---|
|
#18+
Dima TГлавное чтобы пытливость не превращалась в манию велосипедостроения. Да почему такая увереность что ненужно изобретать велосипеды? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.11.2017, 13:55 |
|
||
|
Lock-free очередь
|
|||
|---|---|---|---|
|
#18+
Апаю тему Вопрос пока не решили :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.11.2017, 19:32 |
|
||
|
Lock-free очередь
|
|||
|---|---|---|---|
|
#18+
SOFT FOR YOU, блоки памяти выделяемые в куче какое выравнивание имеют? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2017, 11:56 |
|
||
|
Lock-free очередь
|
|||
|---|---|---|---|
|
#18+
mikronSOFT FOR YOU, PNode(Tail.Value).Next := Node; Эта операция атомарна? А в Delphi вообще есть атомарные операции? А в Delphi вообще есть стандарт? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.12.2017, 22:53 |
|
||
|
Lock-free очередь
|
|||
|---|---|---|---|
|
#18+
mikron, Выравнивание 8 байт. Всё четко ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.12.2017, 17:50 |
|
||
|
Lock-free очередь
|
|||
|---|---|---|---|
|
#18+
MasterZiv, Да, есть атомарные операции AtomicIncrement, AtomicExchange, AtomicCmpExchange ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.12.2017, 17:52 |
|
||
|
|

start [/forum/topic.php?fid=16&msg=39562959&tid=1340221]: |
0ms |
get settings: |
8ms |
get forum list: |
12ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
188ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
58ms |
get tp. blocked users: |
2ms |
| others: | 14ms |
| total: | 303ms |

| 0 / 0 |
