Название: Atomic Lock Отправлено: Igors от Август 01, 2010, 22:48 Добрый день
Хочу сделать такую штуку на QAtomic Код Очевидно что это не будет работать правильно, др. нитка может вклиниться и установить старший бит уже после того как он прочитан Код А как сделать правильно? Спасибо Название: Re: Atomic Lock Отправлено: lit-uriy от Август 01, 2010, 23:55 QMutexLocker?
Название: Re: Atomic Lock Отправлено: SABROG от Август 02, 2010, 09:30 QMutexLocker? Он хочет написать lock-free алгоритм, который будет грузить ядро процессора на 100%, но не блокировать другие потоки. Мутексы с семафорами для этих целей не подходят.Приблизительно так можно сделать. Код
Или так (побыстрее будет на первоначальную проверку): Код
Название: Re: Atomic Lock Отправлено: Igors от Август 02, 2010, 13:41 Он хочет написать lock-free алгоритм, который будет грузить ядро процессора на 100%, но не блокировать другие потоки. Мутексы с семафорами для этих целей не подходят. Совершенно верно :) Однако предложенные Вами варианты страдают тем же дефектом что и начальныйКод
Код
Название: Re: Atomic Lock Отправлено: SABROG от Август 02, 2010, 13:53 Можно так сделать:
Код
Название: Re: Atomic Lock Отправлено: Igors от Август 02, 2010, 14:33 Код
1) state.fetchAndStoreAcquire((int)state); Если значение было изменено между (int) state и fetchAndStoreAcquire, то эти изменения будут убиты. Надо заменить на просто = (QAtomicInt имеет оператор int) 2) testAndSetRelaxed обещает что значение будет установлено, но не гарантирует что др. нитка не вклинится в нашу оборону. Поэтому надо заменить на testAndSetAcquire 3) yieldCurrentThread - дело темное устроит ли это по скорости, вообще неясно как "прокручиваться" наилучшим образом. Так что выделим это в DoNothing С учетом вышеизложенного Код Другие мнения? Название: Re: Atomic Lock Отправлено: SABROG от Август 02, 2010, 14:59 1) state.fetchAndStoreAcquire((int)state); Если значение было изменено между (int) state и fetchAndStoreAcquire, то эти изменения будут убиты. Надо заменить на просто = (QAtomicInt имеет оператор int) Изменения могут быть, но это лишь приведет к одному "холостому" циклу. QAtomicInt не имеет атомарных конструктора и оператора int(), аналогов std::atomic<>::load()/store() в нём нет.2) testAndSetRelaxed обещает что значение будет установлено, но не гарантирует что др. нитка не вклинится в нашу оборону. Поэтому надо заменить на testAndSetAcquire Зато это гарантирует отсутствие атомарной блокировки. Просто позволяем "гоняться" потокам между собой. На этой стадии не важен победитель, так как внутри каждого потока код один и тот же. Зато не будет необходимости синхронизировать потоки.3) yieldCurrentThread - дело темное устроит ли это по скорости, вообще неясно как "прокручиваться" наилучшим образом. Так что выделим это в DoNothing Алгоритм где я применял этот метод был в 2 раза быстрей boost'овского. К тому же это позволяет не расходывать процессорное время на холостые ходы, отдаем ресурсы потоку, который в этом нуждается.С учетом вышеизложенного Тут без fetchAndStoreAcquire() можно запросто получить оптимизацию компилятора или re-ordering.int cachedState = state; if (cachedState >= 1024) Название: Re: Atomic Lock Отправлено: Igors от Август 02, 2010, 15:51 Изменения могут быть, но это лишь приведет к одному "холостому" циклу. Не могу с Вами согласитьсяКод: state.fetchAndStoreAcquire((int)state) Тут без fetchAndStoreAcquire() можно запросто получить оптимизацию компилятора или re-ordering. Да, но здесь это приведет лишь к еще 1 холостому циклу. "Проскочившее" значение будет отсечено дальшеНазвание: Re: Atomic Lock Отправлено: SABROG от Август 02, 2010, 16:30 Не могу с Вами согласиться Код
Да, но здесь это приведет лишь к еще 1 холостому циклу. "Проскочившее" значение будет отсечено дальше Компилятор может это оптимизировать как-нибудь так убрав "лишнюю" переменную: Код
Название: Re: Atomic Lock Отправлено: Igors от Август 02, 2010, 20:17 Код
Код
Название: Re: Atomic Lock Отправлено: SABROG от Август 02, 2010, 20:34 Нет, state и cachedstate не равны, ведь fetchAndStoreAcquire сработал точно и теперь state = 1024 (если его не долбанули по вертикали) Что значит "долбанули по вертикали"?Значение QAtomicInt (_q_value) объявлено volatile, так что не должен. А хоть бы и поместил state на регистр - чем нам это плохо? Та же локальная переменная что и хотели Вопрос в том скопирует ли оптимизатор компилятора переменную в стек/регистер или полезет прямиком в память по адресу. Ведь volatile переменные изначально использовались для получения данных с устройства, например:Код
Название: Re: Atomic Lock Отправлено: Igors от Август 03, 2010, 12:07 Что значит "долбанули по вертикали"? т.е. асинхронно, из др нитки или по прерываниюВопрос в том скопирует ли оптимизатор компилятора переменную в стек/регистер или полезет прямиком в память по адресу. Ведь volatile переменные изначально использовались для получения данных с устройства, например: Я так понимаю что volatile переменная должна всегда честно читаться/писаться "прямиком".Название: Re: Atomic Lock Отправлено: Igors от Август 03, 2010, 12:16 Возможен и др вариант решения
Код Имеется ввиду что счетчик в младших битах - скромное число ниток которое никогда не достигнет 1024 (бит блокировки) |